Version 1.11.0-dev.3.0

Merge commit 'af3b6b2b617fd543f1d16f6d967d06feb702f58d' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0379129..9c36150 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,24 +2,35 @@
 
 ### Core library changes
 
-* In dart:html, appendHtml and insertAdjacentHtml now take validator
-  and treeSanitizer parameters, and the inputs are consistently sanitized.
+* In `dart:html`, `appendHtml` and `insertAdjacentHtml` now take `nodeValidator`
+  and `treeSanitizer` parameters, and the inputs are consistently
+  sanitized. See [45818 announcement]
+  [45818 announcement](https://groups.google.com/a/dartlang.org/forum/#!topic/announce/GVO7EAcPi6A)
 * List iterators may not throw ConcurrentModificationError as eagerly in
   release mode. In checked mode, the modification check is still as eager
   as possible.
-  [r45198](https://code.google.com/p/dart/source/detail?r=45198),
-* Update experimental Isolate API:
-  - Make priority parameters of `Isolate.ping` and `Isolate.kill` methods
+  [r45198](https://code.google.com/p/dart/source/detail?r=45198)
 * `dart:core`
   * Add `unmodifiable` constructor to `List` -
     [r45334](https://code.google.com/p/dart/source/detail?r=45334)
-* `dart:isolate` *Experimental*
-  * Make the `priority` parameter of `Isolate.ping` and `Isolate.kill` methods
-    a named parameter.
+  * Add `unmodifiable` constructor to `Map` -
+    [r45733](https://code.google.com/p/dart/source/detail?r=45733)
+  * Add `empty` constructor to `Iterable` -
+    [dcf0286f](https://github.com/dart-lang/sdk/commit/dcf0286f5385187a68ce9e66318d3bf19abf454b)
+* `dart:isolate`:
+  * Make the priority parameter of `Isolate.ping` and `Isolate.kill` methods
+    a named parameter named `priority`.
   * Remove the `Isolate.AS_EVENT` priority.
   * Add extra `response` parameter to `Isolate.ping` and
     `Isolate.addOnExitListener` -
     [r45092](https://code.google.com/p/dart/source/detail?r=45092)
+  * Remove the experimental state of the API.
+
+### Tool changes
+
+* This is the last release that ships the (unsupported)
+  dart2dart (aka `dart2js --output-type=dart`) utility as part
+  of dart2js
 
 ## 1.10.0 – 2015-04-29
 
diff --git a/DEPS b/DEPS
index 7f898ec..dee9ad3 100644
--- a/DEPS
+++ b/DEPS
@@ -17,6 +17,8 @@
   # If you do not know, use the full path while defining your new deps entry.
   "googlecode_url": "http://%s.googlecode.com/svn",
 
+  "dart_github": "https://github.com/dart-lang/%s.git",
+
   "gyp_rev": "@1752",
   "co19_rev": "@801",
   "chromium_url": "http://src.chromium.org/svn",
@@ -27,8 +29,10 @@
   "analyzer_cli_tag" : "@1.0.1",
   "args_tag": "@0.13.0",
   "barback_rev" : "@29ee90dbcf77cfd64632fa2797a4c8a4f29a4b51",
+  "charcode_tag": "@1.1.0",
   "chrome_rev" : "@19997",
   "clang_rev" : "@28450",
+  "cli_util_tag" : "@0.0.1+2",
   "collection_rev": "@1da9a07f32efa2ba0c391b289e2037391e31da0e",
   "crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
   "csslib_tag" : "@0.12.0",
@@ -49,7 +53,7 @@
   "intl_rev": "@32047558bd220a53c1f4d93a26d54b83533b1475",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "@a38eefd116d910199de205f962af92fed87c164c",
-  "linter_tag": "@0.0.2+2",
+  "linter_tag": "@0.0.2+3",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "markdown_rev": "@56b0fd6c018d6103862d07e8e27407b9ea3b963d",
   "matcher_tag": "@0.12.0",
@@ -60,12 +64,13 @@
   "oauth2_rev": "@1bff41f4d54505c36f2d1a001b83b8b745c452f5",
   "observe_rev": "@eee2b8ec34236fa46982575fbccff84f61202ac6",
   "observatory_pub_packages_rev": "@45565",
+  "package_config_rev": "@286f9cf48448c4563e735a142c6f9442ab57674e",
   "path_rev": "@93b3e2aa1db0ac0c8bab9d341588d77acda60320",
   "petitparser_rev" : "@37878",
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "plugin_tag": "@0.1.0",
   "pool_rev": "@22e12aeb16ad0b626900dbe79e4a25391ddfb28c",
-  "pub_semver_tag": "@1.2.0",
+  "pub_semver_tag": "@1.2.1",
   "scheduled_test_tag": "@0.11.8+1",
   "shelf_rev": "@1e87b79b21ac5e6fa2f93576d6c06eaa65285ef4",
   "smoke_rev" : "@f3361191cc2a85ebc1e4d4c33aec672d7915aba9",
@@ -82,6 +87,8 @@
   "unittest_tag": "@0.11.6",
   "usage_rev": "@b5080dac0d26a5609b266f8fdb0d053bc4c1c638",
   "watcher_tag": "@0.9.5",
+  "when_tag": "@0.2.0+2",
+  "which_tag": "@0.1.3+1",
   "web_components_rev": "@0e636b534d9b12c9e96f841e6679398e91a986ec",
   "WebCore_rev" : "@44061",
   "yaml_rev": "@563a5ffd4a800a2897b8f4dd6b19f2a370df2f2b",
@@ -151,106 +158,118 @@
       Var("observatory_pub_packages_rev"),
 
   Var("dart_root") + "/third_party/dart-services":
-      "https://github.com/dart-lang/dart-services.git" +
+      (Var("dart_github") % "dart-services") +
       Var("dart_services_rev"),
 
   Var("dart_root") + "/third_party/pkg_tested/analyzer_cli":
-      "https://github.com/dart-lang/analyzer_cli.git" + Var("analyzer_cli_tag"),
+      (Var("dart_github") % "analyzer_cli") + Var("analyzer_cli_tag"),
   Var("dart_root") + "/third_party/pkg/args":
-      "https://github.com/dart-lang/args.git" + Var("args_tag"),
+      (Var("dart_github") % "args") + Var("args_tag"),
   Var("dart_root") + "/third_party/pkg/async_await":
-      "https://github.com/dart-lang/async_await.git" + Var("async_await_rev"),
+      (Var("dart_github") % "async_await") + Var("async_await_rev"),
   Var("dart_root") + "/third_party/pkg/barback":
-      "https://github.com/dart-lang/barback.git" + Var("barback_rev"),
+      (Var("dart_github") % "barback") + Var("barback_rev"),
+  Var("dart_root") + "/third_party/pkg/charcode":
+      (Var("dart_github") % "charcode") + Var("charcode_tag"),
+  Var("dart_root") + "/third_party/pkg/cli_util":
+      "https://github.com/dart-lang/cli_util.git" + Var("cli_util_tag"),        
   Var("dart_root") + "/third_party/pkg/collection":
-      "https://github.com/dart-lang/collection.git" + Var("collection_rev"),
+      (Var("dart_github") % "collection") + Var("collection_rev"),
   Var("dart_root") + "/third_party/pkg/crypto":
-      "https://github.com/dart-lang/crypto.git" + Var("crypto_rev"),
+      (Var("dart_github") % "crypto") + Var("crypto_rev"),
   Var("dart_root") + "/third_party/pkg/csslib":
-      "https://github.com/dart-lang/csslib.git" + Var("csslib_tag"),
+      (Var("dart_github") % "csslib") + Var("csslib_tag"),
   Var("dart_root") + "/third_party/pkg_tested/dart_style":
-      "https://github.com/dart-lang/dart_style.git" + Var("dart_style_tag"),
+      (Var("dart_github") % "dart_style") + Var("dart_style_tag"),
   Var("dart_root") + "/third_party/pkg/glob":
-      "https://github.com/dart-lang/glob.git" + Var("glob_rev"),
+      (Var("dart_github") % "glob") + Var("glob_rev"),
   Var("dart_root") + "/third_party/pkg/html":
-      "https://github.com/dart-lang/html.git" + Var("html_tag"),
+      (Var("dart_github") % "html") + Var("html_tag"),
   Var("dart_root") + "/third_party/pkg/http":
-      "https://github.com/dart-lang/http.git" + Var("http_rev"),
+      (Var("dart_github") % "http") + Var("http_rev"),
   Var("dart_root") + "/third_party/pkg/http_multi_server":
-      "https://github.com/dart-lang/http_multi_server.git" +
+      (Var("dart_github") % "http_multi_server") +
       Var("http_multi_server_tag"),
   Var("dart_root") + "/third_party/pkg/http_parser":
-      "https://github.com/dart-lang/http_parser.git" + Var("http_parser_rev"),
+      (Var("dart_github") % "http_parser") + Var("http_parser_rev"),
   Var("dart_root") + "/third_party/pkg/http_throttle":
-      "https://github.com/dart-lang/http_throttle.git" +
+      (Var("dart_github") % "http_throttle") +
       Var("http_throttle_rev"),
   Var("dart_root") + "/third_party/pkg/intl":
-      "https://github.com/dart-lang/intl.git" + Var("intl_rev"),
+      (Var("dart_github") % "intl") + Var("intl_rev"),
   Var("dart_root") + "/third_party/pkg/json_rpc_2":
-      "https://github.com/dart-lang/json_rpc_2.git" + Var("json_rpc_2_rev"),
+      (Var("dart_github") % "json_rpc_2") + Var("json_rpc_2_rev"),
   Var("dart_root") + "/third_party/pkg/linter":
-      "https://github.com/dart-lang/linter.git" + Var("linter_tag"),
+      (Var("dart_github") % "linter") + Var("linter_tag"),
   Var("dart_root") + "/third_party/pkg/logging":
-      "https://github.com/dart-lang/logging.git" + Var("logging_rev"),
+      (Var("dart_github") % "logging") + Var("logging_rev"),
   Var("dart_root") + "/third_party/pkg/markdown":
       "https://github.com/dpeek/dart-markdown.git" + Var("markdown_rev"),
   Var("dart_root") + "/third_party/pkg/matcher":
-      "https://github.com/dart-lang/matcher.git" + Var("matcher_tag"),
+      (Var("dart_github") % "matcher") + Var("matcher_tag"),
   Var("dart_root") + "/third_party/pkg/metatest":
-      "https://github.com/dart-lang/metatest.git" + Var("metatest_rev"),
+      (Var("dart_github") % "metatest") + Var("metatest_rev"),
   Var("dart_root") + "/third_party/pkg/mime":
-      "https://github.com/dart-lang/mime.git" + Var("mime_rev"),
+      (Var("dart_github") % "mime") + Var("mime_rev"),
   Var("dart_root") + "/third_party/pkg/oauth2":
-      "https://github.com/dart-lang/oauth2.git" + Var("oauth2_rev"),
+      (Var("dart_github") % "oauth2") + Var("oauth2_rev"),
   Var("dart_root") + "/third_party/pkg/observe":
-      "https://github.com/dart-lang/observe.git" + Var("observe_rev"),
+      (Var("dart_github") % "observe") + Var("observe_rev"),
+  Var("dart_root") + "/third_party/pkg/package_config":
+      (Var("dart_github") % "package_config") +
+      Var("package_config_rev"),
   Var("dart_root") + "/third_party/pkg/path":
-      "https://github.com/dart-lang/path.git" + Var("path_rev"),
+      (Var("dart_github") % "path") + Var("path_rev"),
   Var("dart_root") + "/third_party/pkg/plugin":
-      "https://github.com/dart-lang/plugin.git" + Var("plugin_tag"),
+      (Var("dart_github") % "plugin") + Var("plugin_tag"),
   Var("dart_root") + "/third_party/pkg/pool":
-      "https://github.com/dart-lang/pool.git" + Var("pool_rev"),
+      (Var("dart_github") % "pool") + Var("pool_rev"),
   Var("dart_root") + "/third_party/pkg/pub_semver":
-      "https://github.com/dart-lang/pub_semver.git" + Var("pub_semver_tag"),
+      (Var("dart_github") % "pub_semver") + Var("pub_semver_tag"),
   Var("dart_root") + "/third_party/pkg/scheduled_test":
-      "https://github.com/dart-lang/scheduled_test.git" +
+      (Var("dart_github") % "scheduled_test") +
       Var("scheduled_test_tag"),
   Var("dart_root") + "/third_party/pkg/shelf":
-      "https://github.com/dart-lang/shelf.git" + Var("shelf_rev"),
+      (Var("dart_github") % "shelf") + Var("shelf_rev"),
   Var("dart_root") + "/third_party/pkg/shelf_web_socket":
-      "https://github.com/dart-lang/shelf_web_socket.git" +
+      (Var("dart_github") % "shelf_web_socket") +
       Var("shelf_web_socket_rev"),
   Var("dart_root") + "/third_party/pkg/smoke":
-      "https://github.com/dart-lang/smoke.git" + Var("smoke_rev"),
+      (Var("dart_github") % "smoke") + Var("smoke_rev"),
   Var("dart_root") + "/third_party/pkg/source_maps":
-      "https://github.com/dart-lang/source_maps.git" + Var("source_maps_rev"),
+      (Var("dart_github") % "source_maps") + Var("source_maps_rev"),
   Var("dart_root") + "/third_party/pkg/source_span":
-      "https://github.com/dart-lang/source_span.git" + Var("source_span_rev"),
+      (Var("dart_github") % "source_span") + Var("source_span_rev"),
   Var("dart_root") + "/third_party/pkg/stack_trace":
-      "https://github.com/dart-lang/stack_trace.git" + Var("stack_trace_tag"),
+      (Var("dart_github") % "stack_trace") + Var("stack_trace_tag"),
   Var("dart_root") + "/third_party/pkg/string_scanner":
-      "https://github.com/dart-lang/string_scanner.git" +
+      (Var("dart_github") % "string_scanner") +
       Var("string_scanner_rev"),
   Var("dart_root") + "/third_party/sunflower":
-      "https://github.com/dart-lang/sample-sunflower.git" +
+      (Var("dart_github") % "sample-sunflower") +
       Var("sunflower_rev"),
   Var("dart_root") + "/third_party/pkg/test":
-      "https://github.com/dart-lang/test.git" + Var("test_tag"),
+      (Var("dart_github") % "test") + Var("test_tag"),
   Var("dart_root") + "/third_party/pkg/test_reflective_loader":
-      "https://github.com/dart-lang/test_reflective_loader.git" + Var("test_reflective_loader_tag"),
+      (Var("dart_github") % "test_reflective_loader") + 
+      Var("test_reflective_loader_tag"),
   Var("dart_root") + "/third_party/pkg/unittest":
-      "https://github.com/dart-lang/test.git" + Var("unittest_tag"),
+      (Var("dart_github") % "test") + Var("unittest_tag"),
   Var("dart_root") + "/third_party/pkg/usage":
-      "https://github.com/dart-lang/usage.git" + Var("usage_rev"),
+      (Var("dart_github") % "usage") + Var("usage_rev"),
   Var("dart_root") + "/third_party/pkg/utf":
-      "https://github.com/dart-lang/utf.git" + Var("utf_rev"),
+      (Var("dart_github") % "utf") + Var("utf_rev"),
   Var("dart_root") + "/third_party/pkg/watcher":
-      "https://github.com/dart-lang/watcher.git" + Var("watcher_tag"),
+      (Var("dart_github") % "watcher") + Var("watcher_tag"),
   Var("dart_root") + "/third_party/pkg/web_components":
-      "https://github.com/dart-lang/web-components.git" +
+      (Var("dart_github") % "web-components") +
       Var("web_components_rev"),
+  Var("dart_root") + "/third_party/pkg/when":
+      "https://github.com/dart-lang/when.git" + Var("when_tag"),    
+  Var("dart_root") + "/third_party/pkg/which":
+      "https://github.com/dart-lang/which.git"+ Var("which_tag"),    
   Var("dart_root") + "/third_party/pkg/yaml":
-      "https://github.com/dart-lang/yaml.git" + Var("yaml_rev"),
+      (Var("dart_github") % "yaml") + Var("yaml_rev"),
 
   # These specific versions of barback and source_maps are used for testing and
   # should be pulled from bleeding_edge even on channels.
diff --git a/README b/README
deleted file mode 100644
index 3b2b566..0000000
--- a/README
+++ /dev/null
@@ -1,18 +0,0 @@
-This is the repository of the Dart programming language and its associated
-tools, libraries, and samples.
-
-For license information, please see LICENSE.
-
-You can find more about Dart online at http://dartlang.org or
-http://code.google.com/p/dart.
-
-Here's a brief guide to what's in here:
-
-lib/           Libraries that ship with the Dart runtime (core, html, etc.).
-pkg/           Packages that are not shipped with the core runtime.
-runtime/       Dart VM and code for running it as a standalone app.
-samples/       Sample Dart programs.
-tests/         Automated tests.
-third_party/   External dependencies.
-tools/         Build scripts, text editor support files, etc.
-utils/         Utilities for Dart applications.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7b2589e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+# Dart
+
+[Dart][website] is an open-source, scalable programming language, with robust
+libraries and runtimes, for building web, server, and mobile apps.
+
+## Using Dart
+
+Visit the [dartlang.org][website] to learn more about the
+[language][lang], [tools][tools],
+[getting started][codelab], and more.
+
+Browse [pub.dartlang.org][pubsite] for more packages and libraries contributed
+by the community and the Dart team.
+
+## Contributing to Dart
+
+The easiest way to contribute to Dart is to [file issues][dartbug].
+
+You can also contribute patches, as described in [Contributing][contrib].
+
+## License
+
+See [LICENSE][license].
+
+[website]: https://www.dartlang.org
+[license]: https://github.com/dart-lang/sdk/blob/master/LICENSE
+[repo]: https://github.com/dart-lang/sdk
+[lang]: https://www.dartlang.org/docs/dart-up-and-running/ch02.html
+[tools]: https://www.dartlang.org/tools/
+[codelab]: https://www.dartlang.org/codelabs/darrrt/
+[dartbug]: http://dartbug.com
+[contrib]: https://github.com/dart-lang/sdk/wiki/Contributing
+[pubsite]: https://pub.dartlang.org
diff --git a/create_sdk.gyp b/create_sdk.gyp
index 721066a..0ca1c9a 100644
--- a/create_sdk.gyp
+++ b/create_sdk.gyp
@@ -11,7 +11,6 @@
         'runtime/dart-runtime.gyp:dart',
         'utils/compiler/compiler.gyp:dart2js',
         'utils/pub/pub.gyp:pub',
-        'utils/pub/pub.gyp:core_stubs',
         'utils/dartfmt/dartfmt.gyp:dartfmt',
         'utils/analysis_server/analysis_server.gyp:analysis_server',
         'utils/dartanalyzer/dartanalyzer.gyp:dartanalyzer',
@@ -38,7 +37,6 @@
             '<(SHARED_INTERMEDIATE_DIR)/pub.dart.snapshot',
             '<(SHARED_INTERMEDIATE_DIR)/dartanalyzer.dart.snapshot',
             '<(SHARED_INTERMEDIATE_DIR)/dartfmt.dart.snapshot',
-            '<(SHARED_INTERMEDIATE_DIR)/core_stubs/dart_io.dart',
             '<(SHARED_INTERMEDIATE_DIR)/analysis_server.dart.snapshot',
             'tools/VERSION'
           ],
diff --git a/pkg/analysis_server/lib/plugin/analyzed_files.dart b/pkg/analysis_server/lib/plugin/analyzed_files.dart
new file mode 100644
index 0000000..12c9214
--- /dev/null
+++ b/pkg/analysis_server/lib/plugin/analyzed_files.dart
@@ -0,0 +1,32 @@
+// 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.
+
+/**
+ * Support for client code that extends the set of files being analyzed by the
+ * analysis server.
+ *
+ * Plugins can register a function that takes a [File] and returns a [bool]
+ * indicating whether the plugin is interested in having that file be analyzed.
+ * The analysis server will invoke the contributed functions and analyze the
+ * file if at least one of the functions returns `true`. (The server is not
+ * required to invoke every function with every file.)
+ */
+library analysis_server.plugin.analyzed_files;
+
+import 'package:analysis_server/src/plugin/server_plugin.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:plugin/plugin.dart';
+
+/**
+ * The identifier of the extension point that allows plugins to register
+ * functions that can cause files to be analyzed. The object used as an
+ * extension must be a [ShouldAnalyzeFile] function.
+ */
+final String ANALYZE_FILE_EXTENSION_POINT_ID = Plugin.join(
+    ServerPlugin.UNIQUE_IDENTIFIER, ServerPlugin.ANALYZE_FILE_EXTENSION_POINT);
+
+/**
+ * A function that returns `true` if the given [file] should be analyzed.
+ */
+typedef bool ShouldAnalyzeFile(File file);
diff --git a/pkg/analysis_server/lib/plugin/assist.dart b/pkg/analysis_server/lib/plugin/assist.dart
index f578c0d..393a479 100644
--- a/pkg/analysis_server/lib/plugin/assist.dart
+++ b/pkg/analysis_server/lib/plugin/assist.dart
@@ -13,9 +13,8 @@
 import 'package:plugin/plugin.dart';
 
 /**
- * The identifier of the extension point that allows plugins to register new
- * assist contributors with the server. The object used as an extension must be
- * an [AssistContributor].
+ * The identifier of the extension point that allows plugins to register assist
+ * contributors. The object used as an extension must be an [AssistContributor].
  */
 final String ASSIST_CONTRIBUTOR_EXTENSION_POINT_ID = Plugin.join(
     ServerPlugin.UNIQUE_IDENTIFIER,
diff --git a/pkg/analysis_server/lib/plugin/completion.dart b/pkg/analysis_server/lib/plugin/completion.dart
index a1947e5..8fd6159 100644
--- a/pkg/analysis_server/lib/plugin/completion.dart
+++ b/pkg/analysis_server/lib/plugin/completion.dart
@@ -13,9 +13,9 @@
 import 'package:plugin/plugin.dart';
 
 /**
- * The identifier of the extension point that allows plugins to register new
- * code completion contributors with the server. The object used as an extension
- * must be a [CompletionContributor].
+ * The identifier of the extension point that allows plugins to register code
+ * completion contributors. The object used as an extension must be a
+ * [CompletionContributor].
  */
 final String COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID = Plugin.join(
     ServerPlugin.UNIQUE_IDENTIFIER,
diff --git a/pkg/analysis_server/lib/plugin/fix.dart b/pkg/analysis_server/lib/plugin/fix.dart
index 8045624..45f69a6 100644
--- a/pkg/analysis_server/lib/plugin/fix.dart
+++ b/pkg/analysis_server/lib/plugin/fix.dart
@@ -13,9 +13,8 @@
 import 'package:plugin/plugin.dart';
 
 /**
- * The identifier of the extension point that allows plugins to register new
- * fix contributors with the server. The object used as an extension must be a
- * [FixContributor].
+ * The identifier of the extension point that allows plugins to register fix
+ * contributors. The object used as an extension must be a [FixContributor].
  */
 final String FIX_CONTRIBUTOR_EXTENSION_POINT_ID = Plugin.join(
     ServerPlugin.UNIQUE_IDENTIFIER,
diff --git a/pkg/analysis_server/lib/plugin/index.dart b/pkg/analysis_server/lib/plugin/index.dart
index e8bcf89..096c28d 100644
--- a/pkg/analysis_server/lib/plugin/index.dart
+++ b/pkg/analysis_server/lib/plugin/index.dart
@@ -13,9 +13,8 @@
 import 'package:plugin/plugin.dart';
 
 /**
- * The identifier of the extension point that allows plugins to register new
- * index contributors with the server. The object used as an extension must be
- * an [IndexContributor].
+ * The identifier of the extension point that allows plugins to register index
+ * contributors. The object used as an extension must be an [IndexContributor].
  */
 final String INDEX_CONTRIBUTOR_EXTENSION_POINT_ID = Plugin.join(
     ServerPlugin.UNIQUE_IDENTIFIER,
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 1b7bda3..40a4458 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -8,12 +8,14 @@
 import 'dart:collection';
 import 'dart:math' show max;
 
+import 'package:analysis_server/plugin/analyzed_files.dart';
 import 'package:analysis_server/src/analysis_logger.dart';
 import 'package:analysis_server/src/channel/channel.dart';
 import 'package:analysis_server/src/context_manager.dart';
 import 'package:analysis_server/src/operation/operation.dart';
 import 'package:analysis_server/src/operation/operation_analysis.dart';
 import 'package:analysis_server/src/operation/operation_queue.dart';
+import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart' hide Element;
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/index/index.dart';
@@ -97,6 +99,11 @@
   final SearchEngine searchEngine;
 
   /**
+   * The plugin associated with this analysis server.
+   */
+  final ServerPlugin serverPlugin;
+
+  /**
    * [ContextManager] which handles the mapping from analysis roots
    * to context directories.
    */
@@ -250,8 +257,9 @@
    */
   AnalysisServer(this.channel, this.resourceProvider,
       OptimizingPubPackageMapProvider packageMapProvider, Index _index,
-      AnalysisServerOptions analysisServerOptions, this.defaultSdk,
-      this.instrumentationService, {this.rethrowExceptions: true})
+      this.serverPlugin, AnalysisServerOptions analysisServerOptions,
+      this.defaultSdk, this.instrumentationService,
+      {this.rethrowExceptions: true})
       : index = _index,
         searchEngine = _index != null ? createSearchEngine(_index) : null {
     _performance = performanceDuringStartup;
@@ -281,6 +289,7 @@
         new ServerConnectedParams(VERSION).toNotification();
     channel.sendNotification(notification);
     channel.listen(handleRequest, onDone: done, onError: error);
+    handlers = serverPlugin.createDomains(this);
   }
 
   /**
@@ -1374,6 +1383,24 @@
   }
 
   @override
+  bool shouldFileBeAnalyzed(File file) {
+    List<ShouldAnalyzeFile> functions =
+        analysisServer.serverPlugin.analyzeFileFunctions;
+    for (ShouldAnalyzeFile shouldAnalyzeFile in functions) {
+      if (shouldAnalyzeFile(file)) {
+        // Emacs creates dummy links to track the fact that a file is open for
+        // editing and has unsaved changes (e.g. having unsaved changes to
+        // 'foo.dart' causes a link '.#foo.dart' to be created, which points to
+        // the non-existent file 'username@hostname.pid'. To avoid these dummy
+        // links causing the analyzer to thrash, just ignore links to
+        // non-existent files.
+        return file.exists;
+      }
+    }
+    return false;
+  }
+
+  @override
   void updateContextPackageUriResolver(
       Folder contextFolder, UriResolver packageUriResolver) {
     AnalysisContext context = analysisServer.folderMap[contextFolder];
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index e010a3e..bfa8cb6 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -295,6 +295,11 @@
   }
 
   /**
+   * Return `true` if the given [file] should be analyzed.
+   */
+  bool shouldFileBeAnalyzed(File file);
+
+  /**
    * Called when the package map for a context has changed.
    */
   void updateContextPackageUriResolver(
@@ -321,7 +326,7 @@
       // add files, recurse into folders
       if (child is File) {
         // ignore if should not be analyzed at all
-        if (!_shouldFileBeAnalyzed(child)) {
+        if (!shouldFileBeAnalyzed(child)) {
           continue;
         }
         // ignore if was not excluded
@@ -366,7 +371,7 @@
       }
       // add files, recurse into folders
       if (child is File) {
-        if (_shouldFileBeAnalyzed(child)) {
+        if (shouldFileBeAnalyzed(child)) {
           Source source = createSourceInContext(info.context, child);
           changeSet.addedSource(source);
           info.sources[path] = source;
@@ -580,7 +585,7 @@
         // that case don't add it.
         if (resource is File) {
           File file = resource;
-          if (_shouldFileBeAnalyzed(file)) {
+          if (shouldFileBeAnalyzed(file)) {
             ChangeSet changeSet = new ChangeSet();
             Source source = createSourceInContext(info.context, file);
             changeSet.addedSource(source);
@@ -706,19 +711,6 @@
     Uri uri = context.sourceFactory.restoreUri(source);
     return file.createSource(uri);
   }
-
-  static bool _shouldFileBeAnalyzed(File file) {
-    if (!(AnalysisEngine.isDartFileName(file.path) ||
-        AnalysisEngine.isHtmlFileName(file.path))) {
-      return false;
-    }
-    // Emacs creates dummy links to track the fact that a file is open for
-    // editing and has unsaved changes (e.g. having unsaved changes to
-    // 'foo.dart' causes a link '.#foo.dart' to be created, which points to the
-    // non-existent file 'username@hostname.pid'.  To avoid these dummy links
-    // causing the analyzer to thrash, just ignore links to non-existent files.
-    return file.exists;
-  }
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index d6e2ec5..773af6e 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -221,6 +221,11 @@
         options.hint = newOptions.generateHints;
       });
     }
+    if (newOptions.generateLints != null) {
+      updaters.add((engine.AnalysisOptionsImpl options) {
+        options.lint = newOptions.generateLints;
+      });
+    }
     server.updateOptions(updaters);
     return new AnalysisUpdateOptionsResult().toResponse(request.id);
   }
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index 145f1ba..2b5e4f5 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -154,11 +154,19 @@
     ServerPerformanceStatistics.executionNotifications.makeCurrentWhile(() {
       Source source = notice.source;
       String filePath = source.fullName;
+      // check files
+      bool isDartFile = notice.resolvedDartUnit != null;
+      bool isHtmlFile = notice.resolvedHtmlUnit != null;
+      if (!isDartFile && !isHtmlFile) {
+        return;
+      }
+      // prepare context
       AnalysisContext context = server.getContainingContext(filePath);
       if (context == null) {
         return;
       }
-      if (AnalysisEngine.isDartFileName(filePath)) {
+      // analyze the file
+      if (isDartFile) {
         ExecutableKind kind = ExecutableKind.NOT_EXECUTABLE;
         if (context.isClientLibrary(source)) {
           kind = ExecutableKind.CLIENT;
@@ -171,7 +179,7 @@
         server.sendNotification(
             new ExecutionLaunchDataParams(filePath, kind: kind)
                 .toNotification());
-      } else if (AnalysisEngine.isHtmlFileName(filePath)) {
+      } else if (isHtmlFile) {
         List<Source> libraries = context.getLibrariesReferencedFromHtml(source);
         server.sendNotification(new ExecutionLaunchDataParams(filePath,
             referencedFiles: _getFullNames(libraries)).toNotification());
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 8e11600..8bb2432 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -11,7 +11,6 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/constants.dart';
-import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -43,11 +42,6 @@
   final AnalysisServer server;
 
   /**
-   * The server plugin that defines the extension points used by this handler.
-   */
-  final ServerPlugin plugin;
-
-  /**
    * The [SearchEngine] for this server.
    */
   SearchEngine searchEngine;
@@ -57,7 +51,7 @@
   /**
    * Initialize a newly created handler to handle requests for the given [server].
    */
-  EditDomainHandler(this.server, this.plugin) {
+  EditDomainHandler(this.server) {
     searchEngine = server.searchEngine;
     _newRefactoringManager();
   }
@@ -138,8 +132,8 @@
     Source source = pair.source;
     List<SourceChange> changes = <SourceChange>[];
     if (context != null && source != null) {
-      List<Assist> assists =
-          computeAssists(plugin, context, source, params.offset, params.length);
+      List<Assist> assists = computeAssists(
+          server.serverPlugin, context, source, params.offset, params.length);
       assists.forEach((Assist assist) {
         changes.add(assist.change);
       });
@@ -162,7 +156,8 @@
         for (engine.AnalysisError error in errorInfo.errors) {
           int errorLine = lineInfo.getLocation(error.offset).lineNumber;
           if (errorLine == requestLine) {
-            List<Fix> fixes = computeFixes(plugin, unit.element.context, error);
+            List<Fix> fixes =
+                computeFixes(server.serverPlugin, unit.element.context, error);
             if (fixes.isNotEmpty) {
               AnalysisError serverError =
                   newAnalysisError_fromEngine(lineInfo, error);
diff --git a/pkg/analysis_server/lib/src/plugin/server_plugin.dart b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
index 6aed910..8bed905 100644
--- a/pkg/analysis_server/lib/src/plugin/server_plugin.dart
+++ b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
@@ -8,8 +8,8 @@
 import 'package:analysis_server/completion/completion_core.dart';
 import 'package:analysis_server/edit/assist/assist_core.dart';
 import 'package:analysis_server/edit/fix/fix_core.dart';
+import 'package:analysis_server/plugin/analyzed_files.dart';
 import 'package:analysis_server/plugin/assist.dart';
-//import 'package:analysis_server/plugin/completion.dart';
 import 'package:analysis_server/plugin/fix.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
@@ -21,6 +21,8 @@
 import 'package:analysis_server/src/search/search_domain.dart';
 import 'package:analysis_server/src/services/correction/assist_internal.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:plugin/plugin.dart';
 
 /**
@@ -36,32 +38,38 @@
 class ServerPlugin implements Plugin {
   /**
    * The simple identifier of the extension point that allows plugins to
-   * register new assist contributors with the server.
+   * register functions that can cause files to be analyzed.
+   */
+  static const String ANALYZE_FILE_EXTENSION_POINT = 'analyzeFile';
+
+  /**
+   * The simple identifier of the extension point that allows plugins to
+   * register assist contributors.
    */
   static const String ASSIST_CONTRIBUTOR_EXTENSION_POINT = 'assistContributor';
 
   /**
    * The simple identifier of the extension point that allows plugins to
-   * register new completion contributors with the server.
+   * register completion contributors.
    */
   static const String COMPLETION_CONTRIBUTOR_EXTENSION_POINT =
       'completionContributor';
 
   /**
    * The simple identifier of the extension point that allows plugins to
-   * register new domains with the server.
+   * register domains.
    */
   static const String DOMAIN_EXTENSION_POINT = 'domain';
 
   /**
    * The simple identifier of the extension point that allows plugins to
-   * register new fix contributors with the server.
+   * register fix contributors.
    */
   static const String FIX_CONTRIBUTOR_EXTENSION_POINT = 'fixContributor';
 
   /**
    * The simple identifier of the extension point that allows plugins to
-   * register new index contributors with the server.
+   * register index contributors.
    */
   static const String INDEX_CONTRIBUTOR_EXTENSION_POINT = 'indexContributor';
 
@@ -71,32 +79,36 @@
   static const String UNIQUE_IDENTIFIER = 'analysis_server.core';
 
   /**
-   * The extension point that allows plugins to register new assist contributors
-   * with the server.
+   * The extension point that allows plugins to register functions that can
+   * cause files to be analyzed.
+   */
+  ExtensionPoint analyzeFileExtensionPoint;
+
+  /**
+   * The extension point that allows plugins to register assist contributors.
    */
   ExtensionPoint assistContributorExtensionPoint;
 
   /**
-   * The extension point that allows plugins to register new completion
-   * contributors with the server.
+   * The extension point that allows plugins to register completion
+   * contributors.
    */
   ExtensionPoint completionContributorExtensionPoint;
 
   /**
-   * The extension point that allows plugins to register new domains with the
+   * The extension point that allows plugins to register domains with the
    * server.
    */
   ExtensionPoint domainExtensionPoint;
 
   /**
-   * The extension point that allows plugins to register new fix contributors
-   * with the server.
+   * The extension point that allows plugins to register fix contributors with
+   * the server.
    */
   ExtensionPoint fixContributorExtensionPoint;
 
   /**
-   * The extension point that allows plugins to register new index contributors
-   * with the server.
+   * The extension point that allows plugins to register index contributors.
    */
   ExtensionPoint indexContributorExtensionPoint;
 
@@ -106,6 +118,13 @@
   ServerPlugin();
 
   /**
+   * Return a list containing all of the functions that can cause files to be
+   * analyzed.
+   */
+  List<ShouldAnalyzeFile> get analyzeFileFunctions =>
+      analyzeFileExtensionPoint.extensions;
+
+  /**
    * Return a list containing all of the assist contributors that were
    * contributed.
    */
@@ -150,6 +169,8 @@
 
   @override
   void registerExtensionPoints(RegisterExtensionPoint registerExtensionPoint) {
+    analyzeFileExtensionPoint = registerExtensionPoint(
+        ANALYZE_FILE_EXTENSION_POINT, _validateAnalyzeFileExtension);
     assistContributorExtensionPoint = registerExtensionPoint(
         ASSIST_CONTRIBUTOR_EXTENSION_POINT,
         _validateAssistContributorExtension);
@@ -167,6 +188,12 @@
   @override
   void registerExtensions(RegisterExtension registerExtension) {
     //
+    // Register analyze file functions.
+    //
+    registerExtension(ANALYZE_FILE_EXTENSION_POINT_ID,
+        (File file) => AnalysisEngine.isDartFileName(file.path) ||
+            AnalysisEngine.isHtmlFileName(file.path));
+    //
     // Register assist contributors.
     //
     registerExtension(
@@ -184,8 +211,8 @@
         domainId, (AnalysisServer server) => new ServerDomainHandler(server));
     registerExtension(
         domainId, (AnalysisServer server) => new AnalysisDomainHandler(server));
-    registerExtension(domainId,
-        (AnalysisServer server) => new EditDomainHandler(server, this));
+    registerExtension(
+        domainId, (AnalysisServer server) => new EditDomainHandler(server));
     registerExtension(
         domainId, (AnalysisServer server) => new SearchDomainHandler(server));
     registerExtension(domainId,
@@ -208,6 +235,18 @@
    * Validate the given extension by throwing an [ExtensionError] if it is not a
    * valid assist contributor.
    */
+  void _validateAnalyzeFileExtension(Object extension) {
+    if (extension is! ShouldAnalyzeFile) {
+      String id = analyzeFileExtensionPoint.uniqueIdentifier;
+      throw new ExtensionError(
+          'Extensions to $id must be an ShouldAnalyzeFile function');
+    }
+  }
+
+  /**
+   * Validate the given extension by throwing an [ExtensionError] if it is not a
+   * valid assist contributor.
+   */
   void _validateAssistContributorExtension(Object extension) {
     if (extension is! AssistContributor) {
       String id = assistContributorExtensionPoint.uniqueIdentifier;
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 153958f..913e1f2 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -163,12 +163,6 @@
   engine.AnalysisContext context = element.context;
   engine.Source source = element.source;
   if (context == null || source == null) {
-    print('element=$element context=$context source=$source');
-    engine.Element e = element;
-    while (e != null) {
-      print('  (${e.runtimeType}) $e');
-      e = e.enclosingElement;
-    }
     return null;
   }
   String name = element.displayName;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 3de01d3..d4caf3a 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -45,6 +45,8 @@
       'ADD_FIELD_FORMAL_PARAMETERS', 30, "Add final field formal parameters");
   static const ADD_PACKAGE_DEPENDENCY = const FixKind(
       'ADD_PACKAGE_DEPENDENCY', 50, "Add dependency on package '{0}'");
+  static const ADD_PART_OF =
+      const FixKind('ADD_PART_OF', 50, "Add 'part of' directive");
   static const ADD_SUPER_CONSTRUCTOR_INVOCATION = const FixKind(
       'ADD_SUPER_CONSTRUCTOR_INVOCATION', 50,
       "Add super constructor {0} invocation");
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 1b83ef5..bd00f6c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -143,6 +143,9 @@
         CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT) {
       _addFix_createConstructorSuperImplicit();
     }
+    if (errorCode == CompileTimeErrorCode.PART_OF_NON_PART) {
+      _addFix_addPartOfDirective();
+    }
     if (errorCode ==
         CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT) {
       _addFix_createConstructorSuperExplicit();
@@ -344,6 +347,24 @@
     return false;
   }
 
+  void _addFix_addPartOfDirective() {
+    if (node is SimpleStringLiteral && node.parent is PartDirective) {
+      PartDirective directive = node.parent;
+      Source partSource = directive.source;
+      CompilationUnit partUnit =
+          context.getResolvedCompilationUnit2(partSource, unitSource);
+      if (partUnit != null) {
+        CorrectionUtils partUtils = new CorrectionUtils(partUnit);
+        CorrectionUtils_InsertDesc desc = partUtils.getInsertDescTop();
+        String libraryName = unitLibraryElement.name;
+        _addInsertEdit(desc.offset,
+            '${desc.prefix}part of $libraryName;$eol${desc.suffix}',
+            partUnit.element);
+        _addFix(DartFixKind.ADD_PART_OF, []);
+      }
+    }
+  }
+
   void _addFix_boolInsteadOfBoolean() {
     SourceRange range = rf.rangeError(error);
     _addReplaceEdit(range, 'bool');
@@ -351,37 +372,41 @@
   }
 
   void _addFix_createClass() {
-    if (_mayBeTypeIdentifier(node)) {
-      String name = (node as SimpleIdentifier).name;
-      // prepare environment
-      CompilationUnitMember enclosingMember =
-          node.getAncestor((node) => node is CompilationUnitMember);
-      int offset = enclosingMember.end;
-      String prefix = '';
-      // prepare source
-      SourceBuilder sb = new SourceBuilder(file, offset);
-      {
-        sb.append('$eol$eol');
-        sb.append(prefix);
-        // "class"
-        sb.append('class ');
-        // append name
-        {
-          sb.startPosition('NAME');
-          sb.append(name);
-          sb.endPosition();
-        }
-        // no members
-        sb.append(' {');
-        sb.append(eol);
-        sb.append('}');
-      }
-      // insert source
-      _insertBuilder(sb, unitElement);
-      _addLinkedPosition('NAME', sb, rf.rangeNode(node));
-      // add proposal
-      _addFix(DartFixKind.CREATE_CLASS, [name]);
+    if (!_mayBeTypeIdentifier(node)) {
+      return;
     }
+    String name = (node as SimpleIdentifier).name;
+    // prepare environment
+    CompilationUnitMember enclosingMember =
+        node.getAncestor((node) => node.parent is CompilationUnit);
+    if (enclosingMember == null) {
+      return;
+    }
+    int offset = enclosingMember.end;
+    String prefix = '';
+    // prepare source
+    SourceBuilder sb = new SourceBuilder(file, offset);
+    {
+      sb.append('$eol$eol');
+      sb.append(prefix);
+      // "class"
+      sb.append('class ');
+      // append name
+      {
+        sb.startPosition('NAME');
+        sb.append(name);
+        sb.endPosition();
+      }
+      // no members
+      sb.append(' {');
+      sb.append(eol);
+      sb.append('}');
+    }
+    // insert source
+    _insertBuilder(sb, unitElement);
+    _addLinkedPosition('NAME', sb, rf.rangeNode(node));
+    // add proposal
+    _addFix(DartFixKind.CREATE_CLASS, [name]);
   }
 
   /**
@@ -923,8 +948,8 @@
           libName = libName.replaceAll('_', '.');
           SourceEdit edit = new SourceEdit(0, 0, 'library $libName;$eol$eol');
           doSourceChange_addSourceEdit(change, context, source, edit);
+          _addFix(DartFixKind.CREATE_FILE, [source.shortName]);
         }
-        _addFix(DartFixKind.CREATE_FILE, [file]);
       }
     }
   }
@@ -1123,11 +1148,10 @@
       PartDirective partDirective = node.parent;
       Source source = partDirective.source;
       if (source != null) {
-        String file = source.fullName;
         String libName = unitLibraryElement.name;
         SourceEdit edit = new SourceEdit(0, 0, 'part of $libName;$eol$eol');
         doSourceChange_addSourceEdit(change, context, source, edit);
-        _addFix(DartFixKind.CREATE_FILE, [file]);
+        _addFix(DartFixKind.CREATE_FILE, [source.shortName]);
       }
     }
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 67ab4db..9a2a812 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -105,7 +105,7 @@
  * Returns the absolute (non-file) URI or `null`.
  */
 String findAbsoluteUri(AnalysisContext context, String path) {
-  Source fileSource = new NonExistingSource(path, UriKind.FILE_URI);
+  Source fileSource = new NonExistingSource(path, null, UriKind.FILE_URI);
   Uri uri = context.sourceFactory.restoreUri(fileSource);
   if (uri == null) {
     return null;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index 3f24fa9..654fc4f 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -92,7 +92,8 @@
     String refDir = pathContext.dirname(reference.file);
     // try to keep package: URI
     if (_isPackageReference(reference)) {
-      Source newSource = new NonExistingSource(newFile, UriKind.FILE_URI);
+      Source newSource = new NonExistingSource(
+          newFile, pathos.toUri(newFile), UriKind.FILE_URI);
       Uri restoredUri = context.sourceFactory.restoreUri(newSource);
       if (restoredUri != null) {
         return restoredUri.toString();
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index 8fb9b8d..28e08ce 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -75,17 +75,9 @@
     }
 
     analysisServer = new AnalysisServer(serverChannel, resourceProvider,
-        new OptimizingPubPackageMapProvider(resourceProvider, defaultSdk), index,
-        analysisServerOptions, defaultSdk, instrumentationService,
-        rethrowExceptions: false);
-    _initializeHandlers(analysisServer);
+        new OptimizingPubPackageMapProvider(resourceProvider, defaultSdk),
+        index, serverPlugin, analysisServerOptions, defaultSdk,
+        instrumentationService, rethrowExceptions: false);
     analysisServer.userDefinedPlugins = userDefinedPlugins;
   }
-
-  /**
-   * Initialize the handlers to be used by the given [server].
-   */
-  void _initializeHandlers(AnalysisServer server) {
-    server.handlers = serverPlugin.createDomains(server);
-  }
 }
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 52f3479..abb7167 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -6,12 +6,12 @@
 environment:
   sdk: '>=1.9.0 <2.0.0'
 dependencies:
-  analyzer: '>=0.25.0 <0.26.0'
+  analyzer: '>=0.25.1-alpha.0 <0.26.0'
   args: '>=0.13.0 <0.14.0'
   dart_style: '>=0.1.7 <0.2.0'
   logging: any
   path: any
-  plugin: '<0.2.0'
+  plugin: <0.2.0
   watcher: any
   yaml: any
 dev_dependencies:
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 4e1e410..2efad95 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -9,11 +9,13 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
+import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:plugin/manager.dart';
 import 'package:unittest/unittest.dart';
 
 import 'mock_sdk.dart';
@@ -79,9 +81,12 @@
   }
 
   AnalysisServer createAnalysisServer(Index index) {
+    ExtensionManager manager = new ExtensionManager();
+    ServerPlugin serverPlugin = new ServerPlugin();
+    manager.processPlugins([serverPlugin]);
     return new AnalysisServer(serverChannel, resourceProvider,
-        packageMapProvider, index, new AnalysisServerOptions(), new MockSdk(),
-        InstrumentationService.NULL_SERVICE);
+        packageMapProvider, index, serverPlugin, new AnalysisServerOptions(),
+        new MockSdk(), InstrumentationService.NULL_SERVICE);
   }
 
   Index createIndex() {
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index eb6387d..f5ded0f 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -10,6 +10,7 @@
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/domain_server.dart';
 import 'package:analysis_server/src/operation/operation.dart';
+import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
@@ -18,6 +19,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:plugin/manager.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
@@ -115,8 +117,11 @@
     channel = new MockServerChannel();
     resourceProvider = new MemoryResourceProvider();
     packageMapProvider = new MockPackageMapProvider();
+    ExtensionManager manager = new ExtensionManager();
+    ServerPlugin serverPlugin = new ServerPlugin();
+    manager.processPlugins([serverPlugin]);
     server = new AnalysisServer(channel, resourceProvider, packageMapProvider,
-        null, new AnalysisServerOptions(), new MockSdk(),
+        null, serverPlugin, new AnalysisServerOptions(), new MockSdk(),
         InstrumentationService.NULL_SERVICE, rethrowExceptions: true);
   }
 
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 59df06f..95a97b8 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -1019,6 +1019,20 @@
   }
 
   @override
+  bool shouldFileBeAnalyzed(File file) {
+    if (!(AnalysisEngine.isDartFileName(file.path) ||
+        AnalysisEngine.isHtmlFileName(file.path))) {
+      return false;
+    }
+    // Emacs creates dummy links to track the fact that a file is open for
+    // editing and has unsaved changes (e.g. having unsaved changes to
+    // 'foo.dart' causes a link '.#foo.dart' to be created, which points to the
+    // non-existent file 'username@hostname.pid'.  To avoid these dummy links
+    // causing the analyzer to thrash, just ignore links to non-existent files.
+    return file.exists;
+  }
+
+  @override
   void updateContextPackageUriResolver(
       Folder contextFolder, UriResolver packageUriResolver) {
     currentContextPackageUriResolvers[contextFolder.path] = packageUriResolver;
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 881315a..7941190 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -9,10 +9,12 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
+import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:path/path.dart';
+import 'package:plugin/manager.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -34,9 +36,13 @@
   setUp(() {
     serverChannel = new MockServerChannel();
     resourceProvider = new MemoryResourceProvider();
+    ExtensionManager manager = new ExtensionManager();
+    ServerPlugin serverPlugin = new ServerPlugin();
+    manager.processPlugins([serverPlugin]);
     server = new AnalysisServer(serverChannel, resourceProvider,
-        new MockPackageMapProvider(), null, new AnalysisServerOptions(),
-        new MockSdk(), InstrumentationService.NULL_SERVICE);
+        new MockPackageMapProvider(), null, serverPlugin,
+        new AnalysisServerOptions(), new MockSdk(),
+        InstrumentationService.NULL_SERVICE);
     handler = new AnalysisDomainHandler(server);
   });
 
@@ -360,9 +366,13 @@
   AnalysisTestHelper() {
     serverChannel = new MockServerChannel();
     resourceProvider = new MemoryResourceProvider();
+    ExtensionManager manager = new ExtensionManager();
+    ServerPlugin serverPlugin = new ServerPlugin();
+    manager.processPlugins([serverPlugin]);
     server = new AnalysisServer(serverChannel, resourceProvider,
-        new MockPackageMapProvider(), null, new AnalysisServerOptions(),
-        new MockSdk(), InstrumentationService.NULL_SERVICE);
+        new MockPackageMapProvider(), null, serverPlugin,
+        new AnalysisServerOptions(), new MockSdk(),
+        InstrumentationService.NULL_SERVICE);
     handler = new AnalysisDomainHandler(server);
     // listen for notifications
     Stream<Notification> notificationStream =
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 49b56a4..a51cdec 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -13,6 +13,7 @@
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
 import 'package:analysis_server/src/domain_completion.dart';
+import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:analysis_server/src/services/completion/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
@@ -25,6 +26,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:plugin/manager.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -48,9 +50,13 @@
   String testFile2 = '/project/bin/test2.dart';
 
   AnalysisServer createAnalysisServer(Index index) {
+    ExtensionManager manager = new ExtensionManager();
+    ServerPlugin serverPlugin = new ServerPlugin();
+    manager.processPlugins([serverPlugin]);
     return new Test_AnalysisServer(super.serverChannel, super.resourceProvider,
-        super.packageMapProvider, index, new AnalysisServerOptions(),
-        new MockSdk(), InstrumentationService.NULL_SERVICE);
+        super.packageMapProvider, index, serverPlugin,
+        new AnalysisServerOptions(), new MockSdk(),
+        InstrumentationService.NULL_SERVICE);
   }
 
   @override
@@ -651,10 +657,11 @@
   Test_AnalysisServer(ServerCommunicationChannel channel,
       ResourceProvider resourceProvider,
       OptimizingPubPackageMapProvider packageMapProvider, Index index,
-      AnalysisServerOptions analysisServerOptions, DartSdk defaultSdk,
-      InstrumentationService instrumentationService)
+      ServerPlugin serverPlugin, AnalysisServerOptions analysisServerOptions,
+      DartSdk defaultSdk, InstrumentationService instrumentationService)
       : super(channel, resourceProvider, packageMapProvider, index,
-          analysisServerOptions, defaultSdk, instrumentationService);
+          serverPlugin, analysisServerOptions, defaultSdk,
+          instrumentationService);
 
   @override
   AnalysisContext getAnalysisContext(String path) {
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index 78308b9..0bab760 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -9,6 +9,7 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/domain_execution.dart';
+import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
@@ -16,6 +17,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:plugin/manager.dart';
 import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
 
@@ -23,14 +25,6 @@
 import 'mocks.dart';
 import 'operation/operation_queue_test.dart';
 
-/**
- * Return a matcher that will match an [ExecutableFile] if it has the given
- * [source] and [kind].
- */
-Matcher isExecutableFile(Source source, ExecutableKind kind) {
-  return new IsExecutableFile(source.fullName, kind);
-}
-
 main() {
   group('ExecutionDomainHandler', () {
     MemoryResourceProvider provider = new MemoryResourceProvider();
@@ -38,9 +32,13 @@
     ExecutionDomainHandler handler;
 
     setUp(() {
+      ExtensionManager manager = new ExtensionManager();
+      ServerPlugin serverPlugin = new ServerPlugin();
+      manager.processPlugins([serverPlugin]);
       server = new AnalysisServer(new MockServerChannel(), provider,
-          new MockPackageMapProvider(), null, new AnalysisServerOptions(),
-          new MockSdk(), InstrumentationService.NULL_SERVICE);
+          new MockPackageMapProvider(), null, serverPlugin,
+          new AnalysisServerOptions(), new MockSdk(),
+          InstrumentationService.NULL_SERVICE);
       handler = new ExecutionDomainHandler(server);
     });
 
@@ -244,8 +242,8 @@
         source4.fullName,
         source5.fullName
       ];
-      when(server.sendNotification(anyObject)).thenInvoke(
-          (Notification notification) {
+      when(server.sendNotification(anyObject))
+          .thenInvoke((Notification notification) {
         ExecutionLaunchDataParams params =
             new ExecutionLaunchDataParams.fromNotification(notification);
 
@@ -282,6 +280,14 @@
 }
 
 /**
+ * Return a matcher that will match an [ExecutableFile] if it has the given
+ * [source] and [kind].
+ */
+Matcher isExecutableFile(Source source, ExecutableKind kind) {
+  return new IsExecutableFile(source.fullName, kind);
+}
+
+/**
  * A matcher that will match an [ExecutableFile] if it has a specified [source]
  * and [kind].
  */
diff --git a/pkg/analysis_server/test/domain_server_test.dart b/pkg/analysis_server/test/domain_server_test.dart
index 94a932d..d76b376 100644
--- a/pkg/analysis_server/test/domain_server_test.dart
+++ b/pkg/analysis_server/test/domain_server_test.dart
@@ -7,9 +7,11 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/domain_server.dart';
+import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:plugin/manager.dart';
 import 'package:unittest/unittest.dart';
 
 import 'mock_sdk.dart';
@@ -22,9 +24,13 @@
   setUp(() {
     var serverChannel = new MockServerChannel();
     var resourceProvider = new MemoryResourceProvider();
+    ExtensionManager manager = new ExtensionManager();
+    ServerPlugin serverPlugin = new ServerPlugin();
+    manager.processPlugins([serverPlugin]);
     server = new AnalysisServer(serverChannel, resourceProvider,
-        new MockPackageMapProvider(), null, new AnalysisServerOptions(),
-        new MockSdk(), InstrumentationService.NULL_SERVICE);
+        new MockPackageMapProvider(), null, serverPlugin,
+        new AnalysisServerOptions(), new MockSdk(),
+        InstrumentationService.NULL_SERVICE);
     handler = new ServerDomainHandler(server);
   });
 
diff --git a/pkg/analysis_server/test/edit/assists_test.dart b/pkg/analysis_server/test/edit/assists_test.dart
index 3517416..42ca88a 100644
--- a/pkg/analysis_server/test/edit/assists_test.dart
+++ b/pkg/analysis_server/test/edit/assists_test.dart
@@ -7,7 +7,6 @@
 import 'dart:async';
 
 import 'package:analysis_server/src/edit/edit_domain.dart';
-import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:plugin/manager.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -42,9 +41,8 @@
     super.setUp();
     createProject();
     ExtensionManager manager = new ExtensionManager();
-    ServerPlugin plugin = new ServerPlugin();
-    manager.processPlugins([plugin]);
-    handler = new EditDomainHandler(server, plugin);
+    manager.processPlugins([server.serverPlugin]);
+    handler = new EditDomainHandler(server);
   }
 
   Future test_removeTypeAnnotation() async {
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 595f1b3..800b9f8 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -8,7 +8,6 @@
 
 import 'package:analysis_server/src/domain_analysis.dart';
 import 'package:analysis_server/src/edit/edit_domain.dart';
-import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:plugin/manager.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -29,9 +28,8 @@
     super.setUp();
     createProject();
     ExtensionManager manager = new ExtensionManager();
-    ServerPlugin plugin = new ServerPlugin();
-    manager.processPlugins([plugin]);
-    handler = new EditDomainHandler(server, plugin);
+    manager.processPlugins([server.serverPlugin]);
+    handler = new EditDomainHandler(server);
   }
 
   Future test_fixUndefinedClass() async {
diff --git a/pkg/analysis_server/test/edit/format_test.dart b/pkg/analysis_server/test/edit/format_test.dart
index c116db8..8d9d011 100644
--- a/pkg/analysis_server/test/edit/format_test.dart
+++ b/pkg/analysis_server/test/edit/format_test.dart
@@ -7,7 +7,6 @@
 import 'dart:async';
 
 import 'package:analysis_server/src/edit/edit_domain.dart';
-import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:plugin/manager.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -28,9 +27,8 @@
     super.setUp();
     createProject();
     ExtensionManager manager = new ExtensionManager();
-    ServerPlugin plugin = new ServerPlugin();
-    manager.processPlugins([plugin]);
-    handler = new EditDomainHandler(server, plugin);
+    manager.processPlugins([server.serverPlugin]);
+    handler = new EditDomainHandler(server);
   }
 
   Future test_formatNoOp() {
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index dac98eb..d59999f 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -7,7 +7,6 @@
 import 'dart:async';
 
 import 'package:analysis_server/src/edit/edit_domain.dart';
-import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
@@ -670,9 +669,8 @@
     super.setUp();
     createProject();
     ExtensionManager manager = new ExtensionManager();
-    ServerPlugin plugin = new ServerPlugin();
-    manager.processPlugins([plugin]);
-    handler = new EditDomainHandler(server, plugin);
+    manager.processPlugins([server.serverPlugin]);
+    handler = new EditDomainHandler(server);
     server.handlers = [handler];
   }
 
@@ -1713,9 +1711,8 @@
     super.setUp();
     createProject();
     ExtensionManager manager = new ExtensionManager();
-    ServerPlugin plugin = new ServerPlugin();
-    manager.processPlugins([plugin]);
-    handler = new EditDomainHandler(server, plugin);
+    manager.processPlugins([server.serverPlugin]);
+    handler = new EditDomainHandler(server);
     server.handlers = [handler];
   }
 }
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index 18d3052..6aa638c 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_test.dart
@@ -7,7 +7,6 @@
 import 'dart:async';
 
 import 'package:analysis_server/src/edit/edit_domain.dart';
-import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:plugin/manager.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -30,9 +29,8 @@
     super.setUp();
     createProject();
     ExtensionManager manager = new ExtensionManager();
-    ServerPlugin plugin = new ServerPlugin();
-    manager.processPlugins([plugin]);
-    handler = new EditDomainHandler(server, plugin);
+    manager.processPlugins([server.serverPlugin]);
+    handler = new EditDomainHandler(server);
   }
 
   Future test_BAD_doesNotExist() {
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index d23f7a5..78ee244 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/file_system/file_system.dart' as resource;
 import 'package:analyzer/file_system/memory_file_system.dart' as resource;
+import 'package:analyzer/src/context/context.dart' as newContext;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -203,7 +204,11 @@
   @override
   AnalysisContext get context {
     if (_analysisContext == null) {
-      _analysisContext = new SdkAnalysisContext();
+      if (AnalysisEngine.instance.useTaskModel) {
+        _analysisContext = new newContext.SdkAnalysisContext();
+      } else {
+        _analysisContext = new SdkAnalysisContext();
+      }
       SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
       _analysisContext.sourceFactory = factory;
       ChangeSet changeSet = new ChangeSet();
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index f09f8c6..30c16e5 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -162,6 +162,36 @@
 ''');
   }
 
+  void test_addPartOfDirective() {
+    String partCode = r'''
+// Comment first.
+// Comment second.
+
+class A {}
+''';
+    addSource('/part.dart', partCode);
+    resolveTestUnit('''
+library my.lib;
+part 'part.dart';
+''');
+    AnalysisError error = _findErrorToFix();
+    fix = _assertHasFix(DartFixKind.ADD_PART_OF, error);
+    change = fix.change;
+    // apply to "file"
+    List<SourceFileEdit> fileEdits = change.edits;
+    expect(fileEdits, hasLength(1));
+    SourceFileEdit fileEdit = change.edits[0];
+    expect(fileEdit.file, '/part.dart');
+    expect(SourceEdit.applySequence(partCode, fileEdit.edits), r'''
+// Comment first.
+// Comment second.
+
+part of my.lib;
+
+class A {}
+''');
+  }
+
   void test_addSync_BAD_nullFunctionBody() {
     resolveTestUnit('''
 var F = await;
@@ -359,6 +389,27 @@
     _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
   }
 
+  void test_createClass_innerLocalFunction() {
+    resolveTestUnit('''
+f() {
+  g() {
+    Test v = null;
+  }
+}
+''');
+    assertHasFix(DartFixKind.CREATE_CLASS, '''
+f() {
+  g() {
+    Test v = null;
+  }
+}
+
+class Test {
+}
+''');
+    _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
+  }
+
   void test_createConstructor_forFinalFields() {
     errorFilter = (AnalysisError error) {
       return error.message.contains("'a'");
@@ -1078,6 +1129,35 @@
     expect(fileEdit.edits[0].replacement, contains('part of my.lib;'));
   }
 
+  void test_createFile_forPart_inPackageLib() {
+    provider.newFile('/my/pubspec.yaml', r'''
+name: my_test
+''');
+    testFile = '/my/lib/test.dart';
+    addTestSource('''
+library my.lib;
+part 'my_part.dart';
+''', Uri.parse('package:my/test.dart'));
+    // configure SourceFactory
+    UriResolver pkgResolver = new PackageMapUriResolver(
+        provider, {'my': [provider.getResource('/my/lib')],});
+    context.sourceFactory = new SourceFactory(
+        [AbstractContextTest.SDK_RESOLVER, pkgResolver, resourceResolver]);
+    // prepare fix
+    testUnit = resolveLibraryUnit(testSource);
+    AnalysisError error = _findErrorToFix();
+    fix = _assertHasFix(DartFixKind.CREATE_FILE, error);
+    change = fix.change;
+    // validate change
+    List<SourceFileEdit> fileEdits = change.edits;
+    expect(fileEdits, hasLength(1));
+    SourceFileEdit fileEdit = change.edits[0];
+    expect(fileEdit.file, '/my/lib/my_part.dart');
+    expect(fileEdit.fileStamp, -1);
+    expect(fileEdit.edits, hasLength(1));
+    expect(fileEdit.edits[0].replacement, contains('part of my.lib;'));
+  }
+
   void test_createGetter_BAD_inSDK() {
     resolveTestUnit('''
 main(List p) {
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index a06a0da..a3dd17d 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -105,8 +105,8 @@
     };
     context.sourceFactory = new SourceFactory([
       AbstractContextTest.SDK_RESOLVER,
-      resourceResolver,
-      new PackageMapUriResolver(provider, packageMap)
+      new PackageMapUriResolver(provider, packageMap),
+      resourceResolver
     ]);
     // do testing
     String pathA = '/project/bin/a.dart';
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index ccb2149..ee3c747 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -6,6 +6,8 @@
 
 import 'dart:convert';
 
+import 'package:analyzer/task/model.dart';
+
 /**
  * A container with analysis performance constants.
  */
@@ -98,11 +100,15 @@
   String get _timestamp => new DateTime.now().millisecondsSinceEpoch.toString();
 
   /**
-   * Log that an analysis task is being performed in the given [context]. The
-   * task has the given [description].
+   * Log that the given analysis [task] is being performed in the given
+   * [context].
    */
-  void logAnalysisTask(String context, String description) {
+  void logAnalysisTask(String context, dynamic task) {
+    // TODO(brianwilkerson) When the old task model is removed, change the
+    // parameter type to AnalysisTask.
     if (_instrumentationServer != null) {
+      String description =
+          (task is AnalysisTask) ? task.description : task.toString();
       _instrumentationServer
           .log(_join([TAG_ANALYSIS_TASK, context, description]));
     }
diff --git a/pkg/analyzer/lib/plugin/command_line.dart b/pkg/analyzer/lib/plugin/command_line.dart
new file mode 100644
index 0000000..7a6fbd8
--- /dev/null
+++ b/pkg/analyzer/lib/plugin/command_line.dart
@@ -0,0 +1,42 @@
+// 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.
+
+/**
+ * Support for client code that extends command-line tools that use the analysis
+ * engine by adding new command-line arguments.
+ */
+library analyzer.plugin.command_line;
+
+import 'package:analyzer/src/plugin/command_line_plugin.dart';
+import 'package:args/args.dart';
+import 'package:plugin/plugin.dart';
+
+/**
+ * The identifier of the extension point that allows plugins to add new flags
+ * and options to the command-line parser before the parser is used to parse
+ * the command-line. The object used as an extension must be an
+ * [ArgParserContributor].
+ */
+final String PARSER_CONTRIBUTOR_EXTENSION_POINT_ID = Plugin.join(
+    CommandLinePlugin.UNIQUE_IDENTIFIER,
+    CommandLinePlugin.PARSER_CONTRIBUTOR_EXTENSION_POINT);
+
+/**
+ * The identifier of the extension point that allows plugins to access the
+ * result of parsing the command-line. The object used as an extension must be
+ * an [ArgResultsProcessor].
+ */
+final String RESULT_PROCESSOR_EXTENSION_POINT_ID = Plugin.join(
+    CommandLinePlugin.UNIQUE_IDENTIFIER,
+    CommandLinePlugin.RESULT_PROCESSOR_EXTENSION_POINT);
+
+/**
+ * A function that will contribute flags and options to the command-line parser.
+ */
+typedef void ArgParserContributor(ArgParser parser);
+
+/**
+ * A function that will process the results of parsing the command-line.
+ */
+typedef void ArgResultsProcessor(ArgResults results);
diff --git a/pkg/analyzer/lib/source/package_map_resolver.dart b/pkg/analyzer/lib/source/package_map_resolver.dart
index 58240c5..1b0f82f 100644
--- a/pkg/analyzer/lib/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/source/package_map_resolver.dart
@@ -71,7 +71,10 @@
     // Return a NonExistingSource instance.
     // This helps provide more meaningful error messages to users
     // (a missing file error, as opposed to an invalid URI error).
-    return new NonExistingSource(uri.toString(), UriKind.PACKAGE_URI);
+    String fullPath = packageDirs != null && packageDirs.isNotEmpty
+        ? packageDirs.first.canonicalizePath(relPath)
+        : relPath;
+    return new NonExistingSource(fullPath, uri, UriKind.PACKAGE_URI);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 5e50de4..531f84f 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/model.dart';
 import 'package:analyzer/task/model.dart';
 
 /**
@@ -60,6 +61,15 @@
 //  }
 
   /**
+   * Return an iterator returning all of the [Source] targets.
+   */
+  Iterable<Source> get sources {
+    return _partitions
+        .map((CachePartition partition) => partition._sources)
+        .expand((Iterable<Source> sources) => sources);
+  }
+
+  /**
    * Return the entry associated with the given [target].
    */
   CacheEntry get(AnalysisTarget target) {
@@ -102,6 +112,19 @@
   }
 
   /**
+   * Return [Source]s whose full path is equal to the given [path].
+   * Maybe empty, but not `null`.
+   */
+  List<Source> getSourcesWithFullName(String path) {
+    List<Source> sources = <Source>[];
+    for (CachePartition partition in _partitions) {
+      List<Source> partitionSources = partition.getSourcesWithFullName(path);
+      sources.addAll(partitionSources);
+    }
+    return sources;
+  }
+
+  /**
    * Return the state of the given [result] for the given [target].
    *
    * It does not update the cache, if the corresponding [CacheEntry] does not
@@ -279,6 +302,14 @@
   }
 
   /**
+   * Look up the [ResultData] of [descriptor], or add a new one if it isn't
+   * there.
+   */
+  ResultData getResultData(ResultDescriptor descriptor) {
+    return _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor));
+  }
+
+  /**
    * Return the state of the result represented by the given [descriptor].
    */
   CacheState getState(ResultDescriptor descriptor) {
@@ -375,7 +406,7 @@
         _invalidate(descriptor);
       }
     } else {
-      ResultData data = _getResultData(descriptor);
+      ResultData data = getResultData(descriptor);
       data.state = state;
       if (state != CacheState.IN_PROCESS) {
         //
@@ -393,18 +424,28 @@
    */
   /*<V>*/ void setValue(ResultDescriptor /*<V>*/ descriptor, dynamic /*V*/
       value, List<TargetedResult> dependedOn) {
-//    print('  setValue: $descriptor for $target dependedOn=$dependedOn');
     _validateStateChange(descriptor, CacheState.VALID);
     TargetedResult thisResult = new TargetedResult(target, descriptor);
     if (_partition != null) {
       _partition.resultStored(thisResult, value);
     }
-    ResultData data = _getResultData(descriptor);
+    ResultData data = getResultData(descriptor);
     _setDependedOnResults(data, thisResult, dependedOn);
     data.state = CacheState.VALID;
     data.value = value == null ? descriptor.defaultValue : value;
   }
 
+  /**
+   * Set the value of the result represented by the given [descriptor] to the
+   * given [value], keep its dependency, invalidate all the dependent result.
+   */
+  void setValueIncremental(ResultDescriptor descriptor, dynamic value) {
+    ResultData data = getResultData(descriptor);
+    List<TargetedResult> dependedOn = data.dependedOnResults;
+    _invalidate(descriptor);
+    setValue(descriptor, value, dependedOn);
+  }
+
   @override
   String toString() {
     StringBuffer buffer = new StringBuffer();
@@ -418,20 +459,11 @@
   bool _getFlag(int index) => BooleanArray.get(_flags, index);
 
   /**
-   * Look up the [ResultData] of [descriptor], or add a new one if it isn't
-   * there.
-   */
-  ResultData _getResultData(ResultDescriptor descriptor) {
-    return _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor));
-  }
-
-  /**
    * Invalidate the result represented by the given [descriptor] and propagate
    * invalidation to other results that depend on it.
    */
   void _invalidate(ResultDescriptor descriptor) {
     ResultData thisData = _resultMap.remove(descriptor);
-//    print('invalidate: $descriptor for $target');
     if (thisData == null) {
       return;
     }
@@ -444,8 +476,8 @@
       }
     });
     // Invalidate results that depend on this result.
-    List<TargetedResult> dependentResults = thisData.dependentResults;
-    thisData.dependentResults = <TargetedResult>[];
+    Set<TargetedResult> dependentResults = thisData.dependentResults;
+    thisData.dependentResults = new Set<TargetedResult>();
     dependentResults.forEach((TargetedResult dependentResult) {
       CacheEntry entry = _partition.get(dependentResult.target);
       if (entry != null) {
@@ -455,6 +487,7 @@
     // If empty, remove the entry altogether.
     if (_resultMap.isEmpty) {
       _partition._targetMap.remove(target);
+      _partition._removeIfSource(target);
     }
   }
 
@@ -493,7 +526,7 @@
    * their values to the corresponding default values
    */
   void _setErrorState(ResultDescriptor descriptor, CaughtException exception) {
-    ResultData thisData = _getResultData(descriptor);
+    ResultData thisData = getResultData(descriptor);
     // Set the error state.
     _exception = exception;
     thisData.state = CacheState.ERROR;
@@ -606,7 +639,7 @@
    */
   List<TargetedResult> flushToSize() {
     // If still under the cap, done.
-    if (maxSize == -1 || currentSize <= maxSize) {
+    if (currentSize <= maxSize) {
       return TargetedResult.EMPTY_LIST;
     }
     // Flush results until we are under the cap.
@@ -707,6 +740,16 @@
       new HashMap<AnalysisTarget, CacheEntry>();
 
   /**
+   * A set of the [Source] targets.
+   */
+  final HashSet<Source> _sources = new HashSet<Source>();
+
+  /**
+   * A table mapping full paths to lists of [Source]s with these full paths.
+   */
+  final Map<String, List<Source>> _pathToSources = <String, List<Source>>{};
+
+  /**
    * Initialize a newly created cache partition, belonging to the given
    * [context].
    */
@@ -727,6 +770,15 @@
   CacheEntry get(AnalysisTarget target) => _targetMap[target];
 
   /**
+   * Return [Source]s whose full path is equal to the given [path].
+   * Maybe empty, but not `null`.
+   */
+  List<Source> getSourcesWithFullName(String path) {
+    List<Source> sources = _pathToSources[path];
+    return sources != null ? sources : Source.EMPTY_LIST;
+  }
+
+  /**
    * Return `true` if this partition is responsible for the given [target].
    */
   bool isResponsibleFor(AnalysisTarget target);
@@ -750,6 +802,7 @@
     entry._partition = this;
     entry.fixExceptionState();
     _targetMap[target] = entry;
+    _addIfSource(target);
   }
 
   /**
@@ -763,6 +816,7 @@
     if (entry != null) {
       entry._invalidateAll();
     }
+    _removeIfSource(target);
   }
 
   /**
@@ -798,12 +852,25 @@
    */
   int size() => _targetMap.length;
 
+  /**
+   * If the given [target] is a [Source], adds it to [_sources].
+   */
+  void _addIfSource(AnalysisTarget target) {
+    if (target is Source) {
+      _sources.add(target);
+      {
+        String fullName = target.fullName;
+        _pathToSources.putIfAbsent(fullName, () => <Source>[]).add(target);
+      }
+    }
+  }
+
   ResultData _getDataFor(TargetedResult result, {bool orNull: false}) {
     CacheEntry entry = context.analysisCache.get(result.target);
     if (orNull) {
       return entry != null ? entry._resultMap[result.result] : null;
     } else {
-      return entry._getResultData(result.result);
+      return entry.getResultData(result.result);
     }
   }
 
@@ -812,13 +879,39 @@
    */
   CacheFlushManager _getFlushManager(ResultDescriptor descriptor) {
     ResultCachingPolicy policy = descriptor.cachingPolicy;
-    return _flushManagerMap.putIfAbsent(
-        policy, () => new CacheFlushManager(policy, _isPriorityAnalysisTarget));
+    if (identical(policy, DEFAULT_CACHING_POLICY)) {
+      return UnlimitedCacheFlushManager.INSTANCE;
+    }
+    CacheFlushManager manager = _flushManagerMap[policy];
+    if (manager == null) {
+      manager = new CacheFlushManager(policy, _isPriorityAnalysisTarget);
+      _flushManagerMap[policy] = manager;
+    }
+    return manager;
   }
 
   bool _isPriorityAnalysisTarget(AnalysisTarget target) {
     return context.priorityTargets.contains(target);
   }
+
+  /**
+   * If the given [target] is a [Source], removes it from [_sources].
+   */
+  void _removeIfSource(AnalysisTarget target) {
+    if (target is Source) {
+      _sources.remove(target);
+      {
+        String fullName = target.fullName;
+        List<Source> sources = _pathToSources[fullName];
+        if (sources != null) {
+          sources.remove(target);
+          if (sources.isEmpty) {
+            _pathToSources.remove(fullName);
+          }
+        }
+      }
+    }
+  }
 }
 
 /**
@@ -851,7 +944,7 @@
   /**
    * A list of the results that depend on this result.
    */
-  List<TargetedResult> dependentResults = <TargetedResult>[];
+  Set<TargetedResult> dependentResults = new Set<TargetedResult>();
 
   /**
    * Initialize a newly created result holder to represent the value of data
@@ -944,3 +1037,23 @@
   @override
   bool isResponsibleFor(AnalysisTarget target) => true;
 }
+
+/**
+ * [CacheFlushManager] that does nothing, results are never flushed.
+ */
+class UnlimitedCacheFlushManager extends CacheFlushManager {
+  static final CacheFlushManager INSTANCE = new UnlimitedCacheFlushManager();
+
+  UnlimitedCacheFlushManager() : super(DEFAULT_CACHING_POLICY, (_) => false);
+
+  @override
+  void resultAccessed(TargetedResult result) {}
+
+  @override
+  List<TargetedResult> resultStored(TargetedResult newResult, newValue) {
+    return TargetedResult.EMPTY_LIST;
+  }
+
+  @override
+  void targetRemoved(AnalysisTarget target) {}
+}
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index f2c5492..6eee8e9 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/ast.dart';
@@ -21,6 +22,7 @@
         WorkManager;
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/html.dart' as ht;
+import 'package:analyzer/src/generated/incremental_resolver.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -56,6 +58,16 @@
  */
 class AnalysisContextImpl implements InternalAnalysisContext {
   /**
+   * The next context identifier.
+   */
+  static int _NEXT_ID = 0;
+
+  /**
+   * The unique identifier of this context.
+   */
+  final int _id = _NEXT_ID++;
+
+  /**
    * A client-provided name used to identify this context, or `null` if the
    * client has not provided a name.
    */
@@ -291,16 +303,13 @@
 
   @override
   List<Source> get launchableClientLibrarySources {
-    List<Source> sources = new List<Source>();
-    MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      AnalysisTarget target = iterator.key;
-      CacheEntry entry = iterator.value;
-      if (target is Source &&
-          entry.getValue(SOURCE_KIND) == SourceKind.LIBRARY &&
-          !target.isInSystemLibrary &&
-          isClientLibrary(target)) {
-        sources.add(target);
+    List<Source> sources = <Source>[];
+    for (Source source in _cache.sources) {
+      CacheEntry entry = _cache.get(source);
+      if (entry.getValue(SOURCE_KIND) == SourceKind.LIBRARY &&
+          !source.isInSystemLibrary &&
+          isClientLibrary(source)) {
+        sources.add(source);
       }
     }
     return sources;
@@ -308,16 +317,14 @@
 
   @override
   List<Source> get launchableServerLibrarySources {
-    List<Source> sources = new List<Source>();
-    MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      AnalysisTarget target = iterator.key;
-      CacheEntry entry = iterator.value;
-      if (target is Source &&
+    List<Source> sources = <Source>[];
+    for (Source source in _cache.sources) {
+      CacheEntry entry = _cache.get(source);
+      if (source is Source &&
           entry.getValue(SOURCE_KIND) == SourceKind.LIBRARY &&
-          !target.isInSystemLibrary &&
-          isServerLibrary(target)) {
-        sources.add(target);
+          !source.isInSystemLibrary &&
+          isServerLibrary(source)) {
+        sources.add(source);
       }
     }
     return sources;
@@ -364,15 +371,7 @@
 
   @override
   List<Source> get sources {
-    List<Source> sources = new List<Source>();
-    MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      AnalysisTarget target = iterator.key;
-      if (target is Source) {
-        sources.add(target);
-      }
-    }
-    return sources;
+    return _cache.sources.toList();
   }
 
   /**
@@ -692,6 +691,9 @@
     CacheEntry entry = _cache.get(target);
     if (entry == null) {
       entry = new CacheEntry(target);
+      if (target is Source) {
+        entry.modificationTime = getModificationStamp(target);
+      }
       _cache.put(entry);
     }
     return entry;
@@ -769,30 +771,28 @@
     if (sourceKind == null) {
       return Source.EMPTY_LIST;
     }
-    List<Source> htmlSources = new List<Source>();
+    List<Source> htmlSources = <Source>[];
     while (true) {
       if (sourceKind == SourceKind.PART) {
         List<Source> librarySources = getLibrariesContaining(source);
-        MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
-        while (iterator.moveNext()) {
-          CacheEntry entry = iterator.value;
+        for (Source source in _cache.sources) {
+          CacheEntry entry = _cache.get(source);
           if (entry.getValue(SOURCE_KIND) == SourceKind.HTML) {
             List<Source> referencedLibraries =
                 (entry as HtmlEntry).getValue(HtmlEntry.REFERENCED_LIBRARIES);
             if (_containsAny(referencedLibraries, librarySources)) {
-              htmlSources.add(iterator.key);
+              htmlSources.add(source);
             }
           }
         }
       } else {
-        MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
-        while (iterator.moveNext()) {
-          CacheEntry entry = iterator.value;
+        for (Source source in _cache.sources) {
+          CacheEntry entry = _cache.get(source);
           if (entry.getValue(SOURCE_KIND) == SourceKind.HTML) {
             List<Source> referencedLibraries =
                 (entry as HtmlEntry).getValue(HtmlEntry.REFERENCED_LIBRARIES);
             if (_contains(referencedLibraries, source)) {
-              htmlSources.add(iterator.key);
+              htmlSources.add(source);
             }
           }
         }
@@ -822,36 +822,22 @@
     if (kind == SourceKind.LIBRARY) {
       return <Source>[source];
     } else if (kind == SourceKind.PART) {
-      List<Source> libraries = <Source>[];
-      MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
-      while (iterator.moveNext()) {
-        AnalysisTarget target = iterator.key;
-        if (target is Source && getKindOf(target) == SourceKind.LIBRARY) {
-          List<Source> parts = _cache.getValue(target, INCLUDED_PARTS);
-          if (parts.contains(source)) {
-            libraries.add(target);
-          }
-        }
-      }
-      if (libraries.isNotEmpty) {
-        return libraries;
-      }
+      return dartWorkManager.getLibrariesContainingPart(source);
     }
     return Source.EMPTY_ARRAY;
   }
 
   @override
   List<Source> getLibrariesDependingOn(Source librarySource) {
-    List<Source> dependentLibraries = new List<Source>();
-    MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      CacheEntry entry = iterator.value;
+    List<Source> dependentLibraries = <Source>[];
+    for (Source source in _cache.sources) {
+      CacheEntry entry = _cache.get(source);
       if (entry.getValue(SOURCE_KIND) == SourceKind.LIBRARY) {
         if (_contains(entry.getValue(EXPORTED_LIBRARIES), librarySource)) {
-          dependentLibraries.add(iterator.key);
+          dependentLibraries.add(source);
         }
         if (_contains(entry.getValue(IMPORTED_LIBRARIES), librarySource)) {
-          dependentLibraries.add(iterator.key);
+          dependentLibraries.add(source);
         }
       }
     }
@@ -952,15 +938,7 @@
 
   @override
   List<Source> getSourcesWithFullName(String path) {
-    List<Source> sources = <Source>[];
-    MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      AnalysisTarget target = iterator.key;
-      if (target is Source && target.fullName == path) {
-        sources.add(target);
-      }
-    }
-    return sources;
+    return analysisCache.getSourcesWithFullName(path);
   }
 
   @override
@@ -1013,6 +991,16 @@
   }
 
   @override
+  void invalidateLibraryHints(Source librarySource) {
+    List<Source> sources = _cache.getValue(librarySource, UNITS);
+    if (sources != null) {
+      for (Source source in sources) {
+        getCacheEntry(source).setState(HINTS, CacheState.INVALID);
+      }
+    }
+  }
+
+  @override
   bool isClientLibrary(Source librarySource) {
     CacheEntry entry = _cache.get(librarySource);
     return entry.getValue(IS_CLIENT) && entry.getValue(IS_LAUNCHABLE);
@@ -1174,6 +1162,18 @@
   }
 
   @override
+  bool shouldErrorsBeAnalyzed(Source source, Object entry) {
+    CacheEntry entry = analysisCache.get(source);
+    if (source.isInSystemLibrary) {
+      return _options.generateSdkErrors;
+    } else if (!entry.explicitlyAdded) {
+      return _options.generateImplicitErrors;
+    } else {
+      return true;
+    }
+  }
+
+  @override
   void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
       DataDescriptor rowDesc, CacheState state)) {
     // TODO(brianwilkerson) Figure out where this is used and adjust the call
@@ -1250,9 +1250,7 @@
    * given list of [sources].
    */
   void _addSourcesInContainer(List<Source> sources, SourceContainer container) {
-    MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
+    for (Source source in _cache.sources) {
       if (container.contains(source)) {
         sources.add(source);
       }
@@ -1420,12 +1418,11 @@
    * the given [kind].
    */
   List<Source> _getSources(SourceKind kind) {
-    List<Source> sources = new List<Source>();
-    MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      if (iterator.value.getValue(SOURCE_KIND) == kind &&
-          iterator.key is Source) {
-        sources.add(iterator.key);
+    List<Source> sources = <Source>[];
+    for (Source source in _cache.sources) {
+      CacheEntry entry = _cache.get(source);
+      if (entry.getValue(SOURCE_KIND) == kind) {
+        sources.add(source);
       }
     }
     return sources;
@@ -1499,7 +1496,7 @@
         } else if (state == CacheState.ERROR) {
           return;
         }
-        if (_shouldErrorsBeAnalyzed(source, unitEntry)) {
+        if (shouldErrorsBeAnalyzed(source, unitEntry)) {
           state = unitEntry.getState(VERIFY_ERRORS);
           if (state == CacheState.INVALID ||
               (isPriority && state == CacheState.FLUSHED)) {
@@ -1624,7 +1621,7 @@
    */
   void _removeFromPriorityOrder(Source source) {
     int count = _priorityOrder.length;
-    List<Source> newOrder = new List<Source>();
+    List<Source> newOrder = <Source>[];
     for (int i = 0; i < count; i++) {
       if (_priorityOrder[i] != source) {
         newOrder.add(_priorityOrder[i]);
@@ -1636,20 +1633,6 @@
   }
 
   /**
-   * Return `true` if errors should be produced for the given [source]. The
-   * [entry] associated with the source is passed in for efficiency.
-   */
-  bool _shouldErrorsBeAnalyzed(Source source, CacheEntry entry) {
-    if (source.isInSystemLibrary) {
-      return _options.generateSdkErrors;
-    } else if (!entry.explicitlyAdded) {
-      return _options.generateImplicitErrors;
-    } else {
-      return true;
-    }
-  }
-
-  /**
    * Create an entry for the newly added [source] and invalidate any sources
    * that referenced the source before it existed.
    */
@@ -1738,64 +1721,69 @@
    * TODO(scheglov) A hackish, limited incremental resolution implementation.
    */
   bool _tryPoorMansIncrementalResolution(Source unitSource, String newCode) {
-    // TODO(brianwilkerson) Implement this.
-    return false;
-//    return PerformanceStatistics.incrementalAnalysis.makeCurrentWhile(() {
-//      incrementalResolutionValidation_lastUnitSource = null;
-//      incrementalResolutionValidation_lastLibrarySource = null;
-//      incrementalResolutionValidation_lastUnit = null;
-//      // prepare the entry
-//      cache.CacheEntry entry = _cache.get(unitSource);
-//      if (entry == null) {
-//        return false;
-//      }
-//      // prepare the (only) library source
-//      List<Source> librarySources = getLibrariesContaining(unitSource);
-//      if (librarySources.length != 1) {
-//        return false;
-//      }
-//      Source librarySource = librarySources[0];
-//      // prepare the library element
-//      LibraryElement libraryElement = getLibraryElement(librarySource);
-//      if (libraryElement == null) {
-//        return false;
-//      }
-//      // prepare the existing unit
-//      CompilationUnit oldUnit =
-//          getResolvedCompilationUnit2(unitSource, librarySource);
-//      if (oldUnit == null) {
-//        return false;
-//      }
-//      // do resolution
-//      Stopwatch perfCounter = new Stopwatch()..start();
-//      PoorMansIncrementalResolver resolver = new PoorMansIncrementalResolver(
-//          typeProvider, unitSource, entry, oldUnit,
-//          analysisOptions.incrementalApi, analysisOptions);
-//      bool success = resolver.resolve(newCode);
-//      AnalysisEngine.instance.instrumentationService.logPerformance(
-//          AnalysisPerformanceKind.INCREMENTAL, perfCounter,
-//          'success=$success,context_id=$_id,code_length=${newCode.length}');
-//      if (!success) {
-//        return false;
-//      }
-//      // if validation, remember the result, but throw it away
-//      if (analysisOptions.incrementalValidation) {
-//        incrementalResolutionValidation_lastUnitSource = oldUnit.element.source;
-//        incrementalResolutionValidation_lastLibrarySource =
-//            oldUnit.element.library.source;
-//        incrementalResolutionValidation_lastUnit = oldUnit;
-//        return false;
-//      }
-//      // prepare notice
-//      {
-//        LineInfo lineInfo = getLineInfo(unitSource);
-//        ChangeNoticeImpl notice = _getNotice(unitSource);
-//        notice.resolvedDartUnit = oldUnit;
-//        notice.setErrors(entry.allErrors, lineInfo);
-//      }
-//      // OK
-//      return true;
-//    });
+    return PerformanceStatistics.incrementalAnalysis.makeCurrentWhile(() {
+      incrementalResolutionValidation_lastUnitSource = null;
+      incrementalResolutionValidation_lastLibrarySource = null;
+      incrementalResolutionValidation_lastUnit = null;
+      // prepare the entry
+      CacheEntry sourceEntry = _cache.get(unitSource);
+      if (sourceEntry == null) {
+        return false;
+      }
+      // prepare the (only) library source
+      List<Source> librarySources = getLibrariesContaining(unitSource);
+      if (librarySources.length != 1) {
+        return false;
+      }
+      Source librarySource = librarySources[0];
+      CacheEntry unitEntry =
+          _cache.get(new LibrarySpecificUnit(librarySource, unitSource));
+      if (unitEntry == null) {
+        return false;
+      }
+      // prepare the library element
+      LibraryElement libraryElement = getLibraryElement(librarySource);
+      if (libraryElement == null) {
+        return false;
+      }
+      // prepare the existing unit
+      CompilationUnit oldUnit =
+          getResolvedCompilationUnit2(unitSource, librarySource);
+      if (oldUnit == null) {
+        return false;
+      }
+      // do resolution
+      Stopwatch perfCounter = new Stopwatch()..start();
+      PoorMansIncrementalResolver resolver = new PoorMansIncrementalResolver(
+          typeProvider, unitSource, null, sourceEntry, unitEntry, oldUnit,
+          analysisOptions.incrementalApi, analysisOptions);
+      bool success = resolver.resolve(newCode);
+      AnalysisEngine.instance.instrumentationService.logPerformance(
+          AnalysisPerformanceKind.INCREMENTAL, perfCounter,
+          'success=$success,context_id=$_id,code_length=${newCode.length}');
+      if (!success) {
+        return false;
+      }
+      // if validation, remember the result, but throw it away
+      if (analysisOptions.incrementalValidation) {
+        incrementalResolutionValidation_lastUnitSource = oldUnit.element.source;
+        incrementalResolutionValidation_lastLibrarySource =
+            oldUnit.element.library.source;
+        incrementalResolutionValidation_lastUnit = oldUnit;
+        return false;
+      }
+      // prepare notice
+      {
+        ChangeNoticeImpl notice = getNotice(unitSource);
+        notice.resolvedDartUnit = oldUnit;
+        AnalysisErrorInfo errorInfo = getErrors(unitSource);
+        notice.setErrors(errorInfo.errors, errorInfo.lineInfo);
+      }
+      // schedule
+      dartWorkManager.unitIncrementallyResolved(librarySource, unitSource);
+      // OK
+      return true;
+    });
   }
 
   /**
@@ -1808,19 +1796,15 @@
     int consistencyCheckStart = JavaSystem.nanoTime();
     HashSet<Source> changedSources = new HashSet<Source>();
     HashSet<Source> missingSources = new HashSet<Source>();
-    MapIterator<AnalysisTarget, CacheEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      AnalysisTarget target = iterator.key;
-      if (target is Source) {
-        CacheEntry entry = iterator.value;
-        int sourceTime = getModificationStamp(target);
-        if (sourceTime != entry.modificationTime) {
-          changedSources.add(target);
-        }
-        if (entry.exception != null) {
-          if (!exists(target)) {
-            missingSources.add(target);
-          }
+    for (Source source in _cache.sources) {
+      CacheEntry entry = _cache.get(source);
+      int sourceTime = getModificationStamp(source);
+      if (sourceTime != entry.modificationTime) {
+        changedSources.add(source);
+      }
+      if (entry.exception != null) {
+        if (!exists(source)) {
+          missingSources.add(source);
         }
       }
     }
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index 1fb7b7f..fa5360b 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -371,6 +371,7 @@
               element.variable as VariableElementImpl;
           elementAnnotation.evaluationResult = variableElement.evaluationResult;
         } else if (element is ConstructorElementImpl &&
+            element.isConst &&
             constNode.arguments != null) {
           RecordingErrorListener errorListener = new RecordingErrorListener();
           CompilationUnit sourceCompilationUnit =
@@ -427,6 +428,15 @@
             ConstantEvaluationEngine._getConstructorBase(redirectedConstructor);
         callback(redirectedConstructorBase);
         return;
+      } else if (constant.isFactory) {
+        // Factory constructor, but getConstRedirectedConstructor returned
+        // null.  This can happen if we're visiting one of the special external
+        // const factory constructors in the SDK, or if the code contains
+        // errors (such as delegating to a non-const constructor, or delegating
+        // to a constructor that can't be resolved).  In any of these cases,
+        // we'll evaluate calls to this constructor without having to refer to
+        // any other constants.  So we don't need to report any dependencies.
+        return;
       }
       bool superInvocationFound = false;
       List<ConstructorInitializer> initializers = constant.constantInitializers;
@@ -476,8 +486,6 @@
         } else if (element is ConstructorElementImpl && element.isConst) {
           // The annotation is a constructor invocation, so it depends on the
           // constructor.
-          // TODO(paulberry): make sure the right thing happens if the
-          // constructor is non-const.
           callback(element);
         } else {
           // This could happen in the event of invalid code.  The error will be
@@ -826,6 +834,37 @@
   }
 
   /**
+   * Generate an error indicating that the given [constant] is not a valid
+   * compile-time constant because it references at least one of the constants
+   * in the given [cycle], each of which directly or indirectly references the
+   * constant.
+   */
+  void generateCycleError(Iterable<ConstantEvaluationTarget> cycle,
+      ConstantEvaluationTarget constant) {
+    if (constant is VariableElement) {
+      RecordingErrorListener errorListener = new RecordingErrorListener();
+      ErrorReporter errorReporter =
+          new ErrorReporter(errorListener, constant.source);
+      // TODO(paulberry): It would be really nice if we could extract enough
+      // information from the 'cycle' argument to provide the user with a
+      // description of the cycle.
+      errorReporter.reportErrorForElement(
+          CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT, constant, []);
+      (constant as VariableElementImpl).evaluationResult =
+          new EvaluationResultImpl(null, errorListener.errors);
+    } else if (constant is ConstructorElement) {
+      // We don't report cycle errors on constructor declarations since there
+      // is nowhere to put the error information.
+    } else {
+      // Should not happen.  Formal parameter defaults and annotations should
+      // never appear as part of a cycle because they can't be referred to.
+      assert(false);
+      AnalysisEngine.instance.logger.logError(
+          "Constant value computer trying to report a cycle error for a node of type ${constant.runtimeType}");
+    }
+  }
+
+  /**
    * If [constructor] redirects to another const constructor, return the
    * const constructor it redirects to.  Otherwise return `null`.
    */
@@ -902,8 +941,8 @@
       this.context, this.source, this.librarySource, this.annotation);
 
   @override
-  int get hashCode => JenkinsSmiHash.hash4(context.hashCode, source.hashCode,
-      librarySource.hashCode, annotation.hashCode);
+  int get hashCode => JenkinsSmiHash.hash3(
+      source.hashCode, librarySource.hashCode, annotation.hashCode);
 
   @override
   bool operator ==(other) {
@@ -1233,12 +1272,15 @@
         referenceGraph.computeTopologicalSort();
     for (List<ConstantEvaluationTarget> constantsInCycle in topologicalSort) {
       if (constantsInCycle.length == 1) {
-        _computeValueFor(constantsInCycle[0]);
-      } else {
-        for (ConstantEvaluationTarget constant in constantsInCycle) {
-          _generateCycleError(constantsInCycle, constant);
+        ConstantEvaluationTarget constant = constantsInCycle[0];
+        if (!referenceGraph.getTails(constant).contains(constant)) {
+          _computeValueFor(constant);
+          continue;
         }
       }
+      for (ConstantEvaluationTarget constant in constantsInCycle) {
+        evaluationEngine.generateCycleError(constantsInCycle, constant);
+      }
     }
   }
 
@@ -1257,37 +1299,6 @@
     }
     evaluationEngine.computeConstantValue(constant);
   }
-
-  /**
-   * Generate an error indicating that the given [constant] is not a valid
-   * compile-time constant because it references at least one of the constants
-   * in the given [cycle], each of which directly or indirectly references the
-   * constant.
-   */
-  void _generateCycleError(
-      List<ConstantEvaluationTarget> cycle, ConstantEvaluationTarget constant) {
-    if (constant is VariableElement) {
-      RecordingErrorListener errorListener = new RecordingErrorListener();
-      ErrorReporter errorReporter =
-          new ErrorReporter(errorListener, constant.source);
-      // TODO(paulberry): It would be really nice if we could extract enough
-      // information from the 'cycle' argument to provide the user with a
-      // description of the cycle.
-      errorReporter.reportErrorForElement(
-          CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT, constant, []);
-      (constant as VariableElementImpl).evaluationResult =
-          new EvaluationResultImpl(null, errorListener.errors);
-    } else if (constant is ConstructorElement) {
-      // We don't report cycle errors on constructor declarations since there
-      // is nowhere to put the error information.
-    } else {
-      // Should not happen.  Formal parameter defaults and annotations should
-      // never appear as part of a cycle because they can't be referred to.
-      assert(false);
-      AnalysisEngine.instance.logger.logError(
-          "Constant value computer trying to report a cycle error for a node of type ${constant.runtimeType}");
-    }
-  }
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 05e6576..3650fc8 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -7,9 +7,9 @@
 
 library engine;
 
-import "dart:math" as math;
 import 'dart:async';
 import 'dart:collection';
+import 'dart:math' as math;
 
 import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/cache.dart' as cache;
@@ -21,6 +21,7 @@
 import 'package:analyzer/src/task/task_dart.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/model.dart';
+import 'package:plugin/manager.dart';
 
 import '../../instrumentation/instrumentation.dart';
 import 'ast.dart';
@@ -711,6 +712,11 @@
   List<Source> getSourcesWithFullName(String path);
 
   /**
+   * Invalidates hints in the given [librarySource] and included parts.
+   */
+  void invalidateLibraryHints(Source librarySource);
+
+  /**
    * Return `true` if the given [librarySource] is known to be the defining
    * compilation unit of a library that can be run on a client (references
    * 'dart:html', either directly or indirectly).
@@ -2153,9 +2159,7 @@
     return changed;
   }
 
-  /**
-   * Invalidates hints in the given [librarySource] and included parts.
-   */
+  @override
   void invalidateLibraryHints(Source librarySource) {
     SourceEntry sourceEntry = _cache.get(librarySource);
     if (sourceEntry is! DartEntry) {
@@ -2501,6 +2505,17 @@
   }
 
   @override
+  bool shouldErrorsBeAnalyzed(Source source, DartEntry dartEntry) {
+    if (source.isInSystemLibrary) {
+      return _generateSdkErrors;
+    } else if (!dartEntry.explicitlyAdded) {
+      return _generateImplicitErrors;
+    } else {
+      return true;
+    }
+  }
+
+  @override
   void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
       DataDescriptor rowDesc, CacheState state)) {
     bool hintsEnabled = _options.hint;
@@ -3633,7 +3648,7 @@
             return new AnalysisContextImpl_TaskData(
                 new ResolveDartLibraryTask(this, source, librarySource), false);
           }
-          if (_shouldErrorsBeAnalyzed(source, dartEntry)) {
+          if (shouldErrorsBeAnalyzed(source, dartEntry)) {
             CacheState verificationErrorsState = dartEntry.getStateInLibrary(
                 DartEntry.VERIFICATION_ERRORS, librarySource);
             if (verificationErrorsState == CacheState.INVALID ||
@@ -3815,7 +3830,7 @@
               return;
             }
           }
-          if (_shouldErrorsBeAnalyzed(source, dartEntry)) {
+          if (shouldErrorsBeAnalyzed(source, dartEntry)) {
             CacheState verificationErrorsState = dartEntry.getStateInLibrary(
                 DartEntry.VERIFICATION_ERRORS, librarySource);
             if (verificationErrorsState == CacheState.INVALID ||
@@ -3989,47 +4004,6 @@
     }
   }
 
-  /**
-   * Given that the given [source] (with the corresponding [sourceEntry]) has
-   * been invalidated, invalidate all of the libraries that depend on it.
-   */
-  void _propagateInvalidation(Source source, SourceEntry sourceEntry) {
-    if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      htmlEntry.modificationTime = getModificationStamp(source);
-      htmlEntry.invalidateAllInformation();
-      _cache.removedAst(source);
-      _workManager.add(source, SourcePriority.HTML);
-    } else if (sourceEntry is DartEntry) {
-      List<Source> containingLibraries = getLibrariesContaining(source);
-      List<Source> dependentLibraries = getLibrariesDependingOn(source);
-      HashSet<Source> librariesToInvalidate = new HashSet<Source>();
-      for (Source containingLibrary in containingLibraries) {
-        _computeAllLibrariesDependingOn(
-            containingLibrary, librariesToInvalidate);
-      }
-      for (Source dependentLibrary in dependentLibraries) {
-        _computeAllLibrariesDependingOn(
-            dependentLibrary, librariesToInvalidate);
-      }
-      for (Source library in librariesToInvalidate) {
-        _invalidateLibraryResolution(library);
-      }
-      DartEntry dartEntry = _cache.get(source);
-      _removeFromParts(source, dartEntry);
-      dartEntry.modificationTime = getModificationStamp(source);
-      dartEntry.invalidateAllInformation();
-      _cache.removedAst(source);
-      _workManager.add(source, SourcePriority.UNKNOWN);
-    }
-    // reset unit in the notification, it is out of date now
-    ChangeNoticeImpl notice = _pendingNotices[source];
-    if (notice != null) {
-      notice.resolvedDartUnit = null;
-      notice.resolvedHtmlUnit = null;
-    }
-  }
-
 //  /**
 //   * Notify all of the analysis listeners that the given source is no longer included in the set of
 //   * sources that are being analyzed.
@@ -4109,6 +4083,47 @@
 //  }
 
   /**
+   * Given that the given [source] (with the corresponding [sourceEntry]) has
+   * been invalidated, invalidate all of the libraries that depend on it.
+   */
+  void _propagateInvalidation(Source source, SourceEntry sourceEntry) {
+    if (sourceEntry is HtmlEntry) {
+      HtmlEntry htmlEntry = sourceEntry;
+      htmlEntry.modificationTime = getModificationStamp(source);
+      htmlEntry.invalidateAllInformation();
+      _cache.removedAst(source);
+      _workManager.add(source, SourcePriority.HTML);
+    } else if (sourceEntry is DartEntry) {
+      List<Source> containingLibraries = getLibrariesContaining(source);
+      List<Source> dependentLibraries = getLibrariesDependingOn(source);
+      HashSet<Source> librariesToInvalidate = new HashSet<Source>();
+      for (Source containingLibrary in containingLibraries) {
+        _computeAllLibrariesDependingOn(
+            containingLibrary, librariesToInvalidate);
+      }
+      for (Source dependentLibrary in dependentLibraries) {
+        _computeAllLibrariesDependingOn(
+            dependentLibrary, librariesToInvalidate);
+      }
+      for (Source library in librariesToInvalidate) {
+        _invalidateLibraryResolution(library);
+      }
+      DartEntry dartEntry = _cache.get(source);
+      _removeFromParts(source, dartEntry);
+      dartEntry.modificationTime = getModificationStamp(source);
+      dartEntry.invalidateAllInformation();
+      _cache.removedAst(source);
+      _workManager.add(source, SourcePriority.UNKNOWN);
+    }
+    // reset unit in the notification, it is out of date now
+    ChangeNoticeImpl notice = _pendingNotices[source];
+    if (notice != null) {
+      notice.resolvedDartUnit = null;
+      notice.resolvedHtmlUnit = null;
+    }
+  }
+
+  /**
    * Record the results produced by performing a [task] and return the cache
    * entry associated with the results.
    */
@@ -4507,20 +4522,6 @@
   }
 
   /**
-   * Return `true` if errors should be produced for the given [source]. The
-   * [dartEntry] associated with the source is passed in for efficiency.
-   */
-  bool _shouldErrorsBeAnalyzed(Source source, DartEntry dartEntry) {
-    if (source.isInSystemLibrary) {
-      return _generateSdkErrors;
-    } else if (!dartEntry.explicitlyAdded) {
-      return _generateImplicitErrors;
-    } else {
-      return true;
-    }
-  }
-
-  /**
    * Create an entry for the newly added [source] and invalidate any sources
    * that referenced the source before it existed.
    */
@@ -4651,8 +4652,8 @@
       // do resolution
       Stopwatch perfCounter = new Stopwatch()..start();
       PoorMansIncrementalResolver resolver = new PoorMansIncrementalResolver(
-          typeProvider, unitSource, dartEntry, oldUnit,
-          analysisOptions.incrementalApi, analysisOptions);
+          typeProvider, unitSource, getReadableSourceEntryOrNull(unitSource),
+          null, null, oldUnit, analysisOptions.incrementalApi, analysisOptions);
       bool success = resolver.resolve(newCode);
       AnalysisEngine.instance.instrumentationService.logPerformance(
           AnalysisPerformanceKind.INCREMENTAL, perfCounter,
@@ -5769,6 +5770,10 @@
    */
   TaskManager get taskManager {
     if (_taskManager == null) {
+      if (enginePlugin.taskExtensionPoint == null) {
+        // The plugin wasn't used, so tasks are not registered.
+        new ExtensionManager().processPlugins([enginePlugin]);
+      }
       _taskManager = new TaskManager();
       _taskManager.addTaskDescriptors(enginePlugin.taskDescriptors);
       // TODO(brianwilkerson) Create a way to associate different results with
@@ -9001,8 +9006,8 @@
       if (element != null) {
         LibraryElement library = element.library;
         if (library != null) {
-          IncrementalResolver resolver = new IncrementalResolver(
-              element, cache.offset, cache.oldLength, cache.newLength);
+          IncrementalResolver resolver = new IncrementalResolver(null, null,
+              null, element, cache.offset, cache.oldLength, cache.newLength);
           resolver.resolve(parser.updatedNode);
         }
       }
@@ -9160,6 +9165,15 @@
   void recordLibraryElements(Map<Source, LibraryElement> elementMap);
 
   /**
+   * Return `true` if errors should be produced for the given [source].
+   * The [entry] associated with the source is passed in for efficiency.
+   *
+   * TODO(scheglov) remove [entry] after migration to the new task model.
+   * It is not used there anyway.
+   */
+  bool shouldErrorsBeAnalyzed(Source source, Object entry);
+
+  /**
    * Call the given callback function for eache cache item in the context.
    */
   void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 13dd77c..03befb3 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -517,7 +517,7 @@
    */
   static const CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPE =
       const CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_TYPE',
-          "The built-in identifier '{0}' cannot be as a type");
+          "The built-in identifier '{0}' cannot be used as a type");
 
   /**
    * 12.30 Identifier Reference: It is a compile-time error if a built-in
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 789ab42..c22ec67 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -7,8 +7,24 @@
 import 'dart:collection';
 import 'dart:math' as math;
 
+import 'package:analyzer/src/context/cache.dart'
+    show CacheEntry, TargetedResult;
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/task/dart.dart'
+    show
+        HINTS,
+        PARSE_ERRORS,
+        RESOLVE_REFERENCES_ERRORS,
+        RESOLVE_TYPE_NAMES_ERRORS,
+        SCAN_ERRORS,
+        USED_IMPORTED_ELEMENTS,
+        USED_LOCAL_ELEMENTS,
+        VERIFY_ERRORS;
+import 'package:analyzer/task/dart.dart'
+    show DART_ERRORS, LibrarySpecificUnit, PARSED_UNIT, TOKEN_STREAM;
+import 'package:analyzer/task/general.dart' show CONTENT;
+import 'package:analyzer/task/model.dart' show ResultDescriptor;
 
 import 'ast.dart';
 import 'element.dart';
@@ -808,7 +824,17 @@
   /**
    * The [DartEntry] corresponding to the source being resolved.
    */
-  DartEntry entry;
+  DartEntry oldEntry;
+
+  /**
+   * The [CacheEntry] corresponding to the source being resolved.
+   */
+  CacheEntry newSourceEntry;
+
+  /**
+   * The [CacheEntry] corresponding to the [LibrarySpecificUnit] being resolved.
+   */
+  CacheEntry newUnitEntry;
 
   /**
    * The source representing the compilation unit being visited.
@@ -848,15 +874,15 @@
    * Initialize a newly created incremental resolver to resolve a node in the
    * given source in the given library.
    */
-  IncrementalResolver(this._definingUnit, this._updateOffset,
-      this._updateEndOld, this._updateEndNew) {
+  IncrementalResolver(this.oldEntry, this.newSourceEntry, this.newUnitEntry,
+      this._definingUnit, this._updateOffset, this._updateEndOld,
+      this._updateEndNew) {
     _updateDelta = _updateEndNew - _updateEndOld;
     _definingLibrary = _definingUnit.library;
     _librarySource = _definingLibrary.source;
     _source = _definingUnit.source;
     _context = _definingUnit.context;
     _typeProvider = _context.typeProvider;
-    entry = _context.getReadableSourceEntryOrNull(_source);
   }
 
   /**
@@ -999,12 +1025,16 @@
   void _generateLints(AstNode node) {
     LoggingTimer timer = logger.startTimer();
     try {
-      RecordingErrorListener errorListener = new RecordingErrorListener();
-      CompilationUnit unit = node.getAncestor((n) => n is CompilationUnit);
-      LintGenerator lintGenerator =
-          new LintGenerator(<CompilationUnit>[unit], errorListener);
-      lintGenerator.generate();
-      _lints = errorListener.getErrorsForSource(_source);
+      if (_context.analysisOptions.lint) {
+        RecordingErrorListener errorListener = new RecordingErrorListener();
+        CompilationUnit unit = node.getAncestor((n) => n is CompilationUnit);
+        LintGenerator lintGenerator =
+            new LintGenerator(<CompilationUnit>[unit], errorListener);
+        lintGenerator.generate();
+        _lints = errorListener.getErrorsForSource(_source);
+      } else {
+        _lints = AnalysisError.NO_ERRORS;
+      }
     } finally {
       timer.stop('generate lints');
     }
@@ -1068,15 +1098,28 @@
   }
 
   void _shiftEntryErrors() {
-    _shiftErrors(DartEntry.RESOLUTION_ERRORS);
-    _shiftErrors(DartEntry.VERIFICATION_ERRORS);
-    _shiftErrors(DartEntry.HINTS);
-    _shiftErrors(DartEntry.LINTS);
+    if (oldEntry != null) {
+      _shiftEntryErrors_OLD();
+    } else {
+      _shiftEntryErrors_NEW();
+    }
   }
 
-  void _shiftErrors(DataDescriptor<List<AnalysisError>> descriptor) {
-    List<AnalysisError> errors =
-        entry.getValueInLibrary(descriptor, _librarySource);
+  void _shiftEntryErrors_NEW() {
+    _shiftErrors_NEW(RESOLVE_TYPE_NAMES_ERRORS);
+    _shiftErrors_NEW(RESOLVE_REFERENCES_ERRORS);
+    _shiftErrors_NEW(VERIFY_ERRORS);
+    _shiftErrors_NEW(HINTS);
+  }
+
+  void _shiftEntryErrors_OLD() {
+    _shiftErrors_OLD(DartEntry.RESOLUTION_ERRORS);
+    _shiftErrors_OLD(DartEntry.VERIFICATION_ERRORS);
+    _shiftErrors_OLD(DartEntry.HINTS);
+    _shiftErrors_OLD(DartEntry.LINTS);
+  }
+
+  void _shiftErrors(List<AnalysisError> errors) {
     for (AnalysisError error in errors) {
       int errorOffset = error.offset;
       if (errorOffset > _updateOffset) {
@@ -1085,6 +1128,17 @@
     }
   }
 
+  void _shiftErrors_NEW(ResultDescriptor<List<AnalysisError>> descriptor) {
+    List<AnalysisError> errors = newUnitEntry.getValue(descriptor);
+    _shiftErrors(errors);
+  }
+
+  void _shiftErrors_OLD(DataDescriptor<List<AnalysisError>> descriptor) {
+    List<AnalysisError> errors =
+        oldEntry.getValueInLibrary(descriptor, _librarySource);
+    _shiftErrors(errors);
+  }
+
   void _updateElementNameOffsets() {
     LoggingTimer timer = logger.startTimer();
     try {
@@ -1096,21 +1150,39 @@
   }
 
   void _updateEntry() {
+    if (oldEntry != null) {
+      _updateEntry_OLD();
+    } else {
+      _updateEntry_NEW();
+    }
+  }
+
+  void _updateEntry_NEW() {
+    _updateErrors_NEW(RESOLVE_TYPE_NAMES_ERRORS, []);
+    _updateErrors_NEW(RESOLVE_REFERENCES_ERRORS, _resolveErrors);
+    _updateErrors_NEW(VERIFY_ERRORS, _verifyErrors);
+    // invalidate results we don't update incrementally
+    newUnitEntry.setState(USED_IMPORTED_ELEMENTS, CacheState.INVALID);
+    newUnitEntry.setState(USED_LOCAL_ELEMENTS, CacheState.INVALID);
+    newUnitEntry.setState(HINTS, CacheState.INVALID);
+  }
+
+  void _updateEntry_OLD() {
     {
-      List<AnalysisError> oldErrors =
-          entry.getValueInLibrary(DartEntry.RESOLUTION_ERRORS, _librarySource);
+      List<AnalysisError> oldErrors = oldEntry.getValueInLibrary(
+          DartEntry.RESOLUTION_ERRORS, _librarySource);
       List<AnalysisError> errors = _updateErrors(oldErrors, _resolveErrors);
-      entry.setValueInLibrary(
+      oldEntry.setValueInLibrary(
           DartEntry.RESOLUTION_ERRORS, _librarySource, errors);
     }
     {
-      List<AnalysisError> oldErrors = entry.getValueInLibrary(
+      List<AnalysisError> oldErrors = oldEntry.getValueInLibrary(
           DartEntry.VERIFICATION_ERRORS, _librarySource);
       List<AnalysisError> errors = _updateErrors(oldErrors, _verifyErrors);
-      entry.setValueInLibrary(
+      oldEntry.setValueInLibrary(
           DartEntry.VERIFICATION_ERRORS, _librarySource, errors);
     }
-    entry.setValueInLibrary(DartEntry.LINTS, _librarySource, _lints);
+    oldEntry.setValueInLibrary(DartEntry.LINTS, _librarySource, _lints);
   }
 
   List<AnalysisError> _updateErrors(
@@ -1137,6 +1209,13 @@
     return errors;
   }
 
+  void _updateErrors_NEW(ResultDescriptor<List<AnalysisError>> descriptor,
+      List<AnalysisError> newErrors) {
+    List<AnalysisError> oldErrors = newUnitEntry.getValue(descriptor);
+    List<AnalysisError> errors = _updateErrors(oldErrors, newErrors);
+    newUnitEntry.setValueIncremental(descriptor, errors);
+  }
+
   void _verify(AstNode node) {
     LoggingTimer timer = logger.startTimer();
     try {
@@ -1160,7 +1239,22 @@
 class PoorMansIncrementalResolver {
   final TypeProvider _typeProvider;
   final Source _unitSource;
-  final DartEntry _entry;
+
+  /**
+   * The [DartEntry] corresponding to the source being resolved.
+   */
+  DartEntry _oldEntry;
+
+  /**
+   * The [CacheEntry] corresponding to the source being resolved.
+   */
+  CacheEntry _newSourceEntry;
+
+  /**
+   * The [CacheEntry] corresponding to the [LibrarySpecificUnit] being resolved.
+   */
+  CacheEntry _newUnitEntry;
+
   final CompilationUnit _oldUnit;
   final AnalysisOptions _options;
   CompilationUnitElement _unitElement;
@@ -1173,8 +1267,9 @@
   List<AnalysisError> _newScanErrors = <AnalysisError>[];
   List<AnalysisError> _newParseErrors = <AnalysisError>[];
 
-  PoorMansIncrementalResolver(this._typeProvider, this._unitSource, this._entry,
-      this._oldUnit, bool resolveApiChanges, this._options) {
+  PoorMansIncrementalResolver(this._typeProvider, this._unitSource,
+      this._oldEntry, this._newSourceEntry, this._newUnitEntry, this._oldUnit,
+      bool resolveApiChanges, this._options) {
     _resolveApiChanges = resolveApiChanges;
   }
 
@@ -1231,7 +1326,8 @@
             _shiftTokens(firstPair.oldToken);
             {
               IncrementalResolver incrementalResolver = new IncrementalResolver(
-                  _unitElement, _updateOffset, _updateEndOld, _updateEndNew);
+                  _oldEntry, _newSourceEntry, _newUnitEntry, _unitElement,
+                  _updateOffset, _updateEndOld, _updateEndNew);
               incrementalResolver._updateElementNameOffsets();
               incrementalResolver._shiftEntryErrors();
             }
@@ -1316,7 +1412,8 @@
         }
         // perform incremental resolution
         IncrementalResolver incrementalResolver = new IncrementalResolver(
-            _unitElement, _updateOffset, _updateEndOld, _updateEndNew);
+            _oldEntry, _newSourceEntry, _newUnitEntry, _unitElement,
+            _updateOffset, _updateEndOld, _updateEndNew);
         bool success = incrementalResolver.resolve(newNode);
         // check if success
         if (!success) {
@@ -1378,8 +1475,9 @@
     // replace node
     NodeReplacer.replace(oldComment, newComment);
     // update elements
-    IncrementalResolver incrementalResolver = new IncrementalResolver(
-        _unitElement, _updateOffset, _updateEndOld, _updateEndNew);
+    IncrementalResolver incrementalResolver = new IncrementalResolver(_oldEntry,
+        _newSourceEntry, _newUnitEntry, _unitElement, _updateOffset,
+        _updateEndOld, _updateEndNew);
     incrementalResolver._updateElementNameOffsets();
     incrementalResolver._shiftEntryErrors();
     _updateEntry();
@@ -1438,8 +1536,31 @@
   }
 
   void _updateEntry() {
-    _entry.setValue(DartEntry.SCAN_ERRORS, _newScanErrors);
-    _entry.setValue(DartEntry.PARSE_ERRORS, _newParseErrors);
+    if (_oldEntry != null) {
+      _updateEntry_OLD();
+    } else {
+      _updateEntry_NEW();
+    }
+  }
+
+  void _updateEntry_NEW() {
+    _newSourceEntry.setState(DART_ERRORS, CacheState.INVALID);
+    // scan results
+    _newSourceEntry.setState(SCAN_ERRORS, CacheState.INVALID);
+    List<TargetedResult> scanDeps =
+        <TargetedResult>[new TargetedResult(_unitSource, CONTENT)];
+    _newSourceEntry.setValue(SCAN_ERRORS, _newScanErrors, scanDeps);
+    // parse results
+    List<TargetedResult> parseDeps =
+        <TargetedResult>[new TargetedResult(_unitSource, TOKEN_STREAM)];
+    _newSourceEntry.setState(PARSE_ERRORS, CacheState.INVALID);
+    _newSourceEntry.setValue(PARSE_ERRORS, _newParseErrors, parseDeps);
+    _newSourceEntry.setValue(PARSED_UNIT, _oldUnit, parseDeps);
+  }
+
+  void _updateEntry_OLD() {
+    _oldEntry.setValue(DartEntry.SCAN_ERRORS, _newScanErrors);
+    _oldEntry.setValue(DartEntry.PARSE_ERRORS, _newParseErrors);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 8e42379..4900cf6 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -7,12 +7,13 @@
 
 library engine.source;
 
-import "dart:math" as math;
 import 'dart:collection';
+import "dart:math" as math;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/task/model.dart';
+import 'package:path/path.dart' as pathos;
 
 import 'engine.dart';
 import 'java_core.dart';
@@ -323,45 +324,42 @@
  * An implementation of an non-existing [Source].
  */
 class NonExistingSource extends Source {
-  final String _name;
+  @override
+  final String fullName;
+
+  @override
+  final Uri uri;
 
   final UriKind uriKind;
 
-  NonExistingSource(this._name, this.uriKind);
+  NonExistingSource(this.fullName, this.uri, this.uriKind);
 
   @override
   TimestampedData<String> get contents {
-    throw new UnsupportedOperationException("${_name}does not exist.");
+    throw new UnsupportedOperationException('$fullName does not exist.');
   }
 
   @override
   String get encoding {
-    throw new UnsupportedOperationException("${_name}does not exist.");
+    throw new UnsupportedOperationException('$fullName does not exist.');
   }
 
   @override
-  String get fullName => _name;
-
-  @override
-  int get hashCode => _name.hashCode;
+  int get hashCode => fullName.hashCode;
 
   @override
   bool get isInSystemLibrary => false;
 
   @override
-  int get modificationStamp => 0;
+  int get modificationStamp => -1;
 
   @override
-  String get shortName => _name;
+  String get shortName => pathos.basename(fullName);
 
   @override
-  Uri get uri => null;
-
-  @override
-  bool operator ==(Object obj) {
-    if (obj is NonExistingSource) {
-      NonExistingSource other = obj;
-      return other.uriKind == uriKind && (other._name == _name);
+  bool operator ==(Object other) {
+    if (other is NonExistingSource) {
+      return other.uriKind == uriKind && other.fullName == fullName;
     }
     return false;
   }
@@ -371,7 +369,7 @@
 
   @override
   Uri resolveRelativeUri(Uri relativeUri) {
-    throw new UnsupportedOperationException("${_name}does not exist.");
+    throw new UnsupportedOperationException('$fullName does not exist.');
   }
 }
 
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 29d6bbb..d82da2a 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -17,6 +17,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:path/path.dart';
 
 /**
  * The class `ElementFactory` defines utility methods used to create elements for testing
@@ -84,7 +85,8 @@
 
   static CompilationUnitElementImpl compilationUnit(String fileName,
       [Source librarySource]) {
-    Source source = new NonExistingSource(fileName, UriKind.FILE_URI);
+    Source source =
+        new NonExistingSource(fileName, toUri(fileName), UriKind.FILE_URI);
     CompilationUnitElementImpl unit = new CompilationUnitElementImpl(fileName);
     unit.source = source;
     if (librarySource == null) {
@@ -362,7 +364,8 @@
   }
 
   static HtmlElementImpl htmlUnit(AnalysisContext context, String fileName) {
-    Source source = new NonExistingSource(fileName, UriKind.FILE_URI);
+    Source source =
+        new NonExistingSource(fileName, toUri(fileName), UriKind.FILE_URI);
     HtmlElementImpl unit = new HtmlElementImpl(context, fileName);
     unit.source = source;
     return unit;
diff --git a/pkg/analyzer/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart
index 47dd4f6..bd03a10 100644
--- a/pkg/analyzer/lib/src/generated/utilities_collection.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart
@@ -681,6 +681,9 @@
     if (_currentKey == null) {
       throw new NoSuchElementException();
     }
+    if (_currentValue == null) {
+      _currentValue = _map[_currentKey];
+    }
     return _currentValue;
   }
 
@@ -697,7 +700,7 @@
   bool moveNext() {
     if (_keyIterator.moveNext()) {
       _currentKey = _keyIterator.current;
-      _currentValue = _map[_currentKey];
+      _currentValue = null;
       return true;
     } else {
       _currentKey = null;
diff --git a/pkg/analyzer/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
index e62a781..62f4029 100644
--- a/pkg/analyzer/lib/src/generated/utilities_general.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_general.dart
@@ -28,6 +28,8 @@
 
   static int hash2(a, b) => finish(combine(combine(0, a), b));
 
+  static int hash3(a, b, c) => finish(combine(combine(combine(0, a), b), c));
+
   static int hash4(a, b, c, d) =>
       finish(combine(combine(combine(combine(0, a), b), c), d));
 }
diff --git a/pkg/analyzer/lib/src/plugin/command_line_plugin.dart b/pkg/analyzer/lib/src/plugin/command_line_plugin.dart
new file mode 100644
index 0000000..493bced
--- /dev/null
+++ b/pkg/analyzer/lib/src/plugin/command_line_plugin.dart
@@ -0,0 +1,102 @@
+// 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 analyzer.src.plugin.command_line_plugin;
+
+import 'package:analyzer/plugin/command_line.dart';
+import 'package:plugin/plugin.dart';
+
+/**
+ * A plugin that defines the extension points and extensions that are defined by
+ * command-line applications using the analysis engine.
+ */
+class CommandLinePlugin implements Plugin {
+  /**
+   * The simple identifier of the extension point that allows plugins to
+   * register new parser contributors.
+   */
+  static const String PARSER_CONTRIBUTOR_EXTENSION_POINT = 'parserContributor';
+
+  /**
+   * The simple identifier of the extension point that allows plugins to
+   * register new result processors.
+   */
+  static const String RESULT_PROCESSOR_EXTENSION_POINT = 'resultProcessor';
+
+  /**
+   * The unique identifier of this plugin.
+   */
+  static const String UNIQUE_IDENTIFIER = 'command_line.core';
+
+  /**
+   * The extension point that allows plugins to register new parser
+   * contributors.
+   */
+  ExtensionPoint parserContributorExtensionPoint;
+
+  /**
+   * The extension point that allows plugins to register new result processors.
+   */
+  ExtensionPoint resultProcessorExtensionPoint;
+
+  /**
+   * Initialize a newly created plugin.
+   */
+  CommandLinePlugin();
+
+  /**
+   * Return a list containing all of the parser contributors that were
+   * contributed.
+   */
+  List<ArgParserContributor> get parserContributors =>
+      parserContributorExtensionPoint.extensions;
+
+  /**
+   * Return a list containing all of the result processors that were
+   * contributed.
+   */
+  List<ArgParserContributor> get resultProcessors =>
+      resultProcessorExtensionPoint.extensions;
+
+  @override
+  String get uniqueIdentifier => UNIQUE_IDENTIFIER;
+
+  @override
+  void registerExtensionPoints(RegisterExtensionPoint registerExtensionPoint) {
+    parserContributorExtensionPoint = registerExtensionPoint(
+        PARSER_CONTRIBUTOR_EXTENSION_POINT,
+        _validateParserContributorExtension);
+    resultProcessorExtensionPoint = registerExtensionPoint(
+        RESULT_PROCESSOR_EXTENSION_POINT, _validateResultProcessorExtension);
+  }
+
+  @override
+  void registerExtensions(RegisterExtension registerExtension) {
+    // There are no default extensions.
+  }
+
+  /**
+   * Validate the given extension by throwing an [ExtensionError] if it is not a
+   * valid parser contributor.
+   */
+  void _validateParserContributorExtension(Object extension) {
+    if (extension is! ArgParserContributor) {
+      String id = parserContributorExtensionPoint.uniqueIdentifier;
+      throw new ExtensionError(
+          'Extensions to $id must be an ArgParserContributor');
+    }
+  }
+
+  /**
+   * Validate the given extension by throwing an [ExtensionError] if it is not a
+   * valid result processor.
+   */
+  void _validateResultProcessorExtension(Object extension) {
+    if (extension is! ArgResultsProcessor) {
+      String id = resultProcessorExtensionPoint.uniqueIdentifier;
+      throw new ExtensionError(
+          'Extensions to $id must be an ArgResultsProcessor');
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 338e889..4225da6 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -7,10 +7,12 @@
 import 'dart:collection';
 import 'dart:math' as math;
 
+import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart'
+    hide AnalysisCache, AnalysisTask;
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/error_verifier.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -19,6 +21,7 @@
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/general.dart';
 import 'package:analyzer/src/task/model.dart';
 import 'package:analyzer/task/dart.dart';
@@ -29,7 +32,7 @@
  * The [ResultCachingPolicy] for ASTs.
  */
 const ResultCachingPolicy AST_CACHING_POLICY =
-    const SimpleResultCachingPolicy(1024, 512);
+    const SimpleResultCachingPolicy(8192, 8192);
 
 /**
  * The errors produced while resolving a library directives.
@@ -498,20 +501,22 @@
    * given [classElement].
    */
   static Map<String, TaskInput> buildInputs(ClassElement classElement) {
-    // TODO(scheglov) Here we implicitly depend on LIBRARY_ELEMENT5, i.e. that
-    // "supertype" for the "classElement" is set.
-    // We need to make it an explicit dependency.
+    Source librarySource = classElement.library.source;
     DartType superType = classElement.supertype;
     if (superType is InterfaceType) {
       if (classElement.isTypedef || classElement.mixins.isNotEmpty) {
         ClassElement superElement = superType.element;
         return <String, TaskInput>{
+          'libraryDep': LIBRARY_ELEMENT5.of(librarySource),
           SUPER_CONSTRUCTORS: CONSTRUCTORS.of(superElement)
         };
       }
     }
-    // No implicit constructors, no inputs required.
-    return <String, TaskInput>{};
+    // No implicit constructors.
+    // Depend on LIBRARY_ELEMENT5 for invalidation.
+    return <String, TaskInput>{
+      'libraryDep': LIBRARY_ELEMENT5.of(librarySource)
+    };
   }
 
   /**
@@ -667,12 +672,23 @@
     Source source = getRequiredSource();
     CompilationUnit unit = getRequiredInput(PARSED_UNIT_INPUT_NAME);
     //
-    // Process inputs.
+    // Build or reuse CompilationUnitElement.
     //
     unit = AstCloner.clone(unit);
-    CompilationUnitBuilder builder = new CompilationUnitBuilder();
+    AnalysisCache analysisCache =
+        (context as InternalAnalysisContext).analysisCache;
     CompilationUnitElement element =
-        builder.buildCompilationUnit(source, unit, librarySpecificUnit.library);
+        analysisCache.getValue(target, COMPILATION_UNIT_ELEMENT);
+    if (element == null) {
+      CompilationUnitBuilder builder = new CompilationUnitBuilder();
+      element = builder.buildCompilationUnit(
+          source, unit, librarySpecificUnit.library);
+    } else {
+      new DeclarationResolver().resolve(unit, element);
+    }
+    //
+    // Prepare constants.
+    //
     ConstantFinder constantFinder =
         new ConstantFinder(context, source, librarySpecificUnit.library);
     unit.accept(constantFinder);
@@ -1785,6 +1801,9 @@
   TaskDescriptor get descriptor => DESCRIPTOR;
 
   @override
+  bool get handlesDependencyCycles => true;
+
+  @override
   void internalPerform() {
     //
     // Prepare inputs.
@@ -1796,10 +1815,24 @@
     AnalysisContext context = constant.context;
     TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
     //
-    // Compute the value of the constant.
+    // Compute the value of the constant, or report an error if there was a
+    // cycle.
     //
-    new ConstantEvaluationEngine(typeProvider, context.declaredVariables)
-        .computeConstantValue(constant);
+    ConstantEvaluationEngine constantEvaluationEngine =
+        new ConstantEvaluationEngine(typeProvider, context.declaredVariables);
+    if (dependencyCycle == null) {
+      constantEvaluationEngine.computeConstantValue(constant);
+    } else {
+      List<ConstantEvaluationTarget> constantsInCycle =
+          <ConstantEvaluationTarget>[];
+      for (WorkItem workItem in dependencyCycle) {
+        if (workItem.descriptor == DESCRIPTOR) {
+          constantsInCycle.add(workItem.target);
+        }
+      }
+      assert(constantsInCycle.isNotEmpty);
+      constantEvaluationEngine.generateCycleError(constantsInCycle, constant);
+    }
     //
     // Record outputs.
     //
@@ -3244,11 +3277,6 @@
 }
 
 /**
- * The kind of the source closure to build.
- */
-enum _SourceClosureKind { IMPORT, EXPORT, IMPORT_EXPORT }
-
-/**
  * A [TaskInput] whose value is a list of library sources imported or exported,
  * directly or indirectly by the target [Source].
  */
@@ -3278,6 +3306,11 @@
 }
 
 /**
+ * The kind of the source closure to build.
+ */
+enum _SourceClosureKind { IMPORT, EXPORT, IMPORT_EXPORT }
+
+/**
  * A [TaskInputBuilder] to build values for [_ImportSourceClosureTaskInput].
  */
 class _SourceClosureTaskInputBuilder implements TaskInputBuilder<List<Source>> {
@@ -3320,6 +3353,12 @@
   }
 
   @override
+  void currentValueNotAvailable() {
+    // Nothing needs to be done.  moveNext() will simply go on to the next new
+    // source.
+  }
+
+  @override
   bool moveNext() {
     if (_newSources.isEmpty) {
       return false;
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index 66f7392..6d3e6eb 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.dart
@@ -12,6 +12,7 @@
         AnalysisEngine,
         AnalysisErrorInfo,
         AnalysisErrorInfoImpl,
+        AnalysisOptions,
         CacheState,
         InternalAnalysisContext;
 import 'package:analyzer/src/generated/error.dart';
@@ -67,6 +68,18 @@
   final LinkedHashSet<Source> librarySourceQueue = new LinkedHashSet<Source>();
 
   /**
+   * A table mapping library sources to the part sources they include.
+   */
+  final HashMap<Source, List<Source>> libraryPartsMap =
+      new HashMap<Source, List<Source>>();
+
+  /**
+   * A table mapping part sources to the library sources that include them.
+   */
+  final HashMap<Source, List<Source>> partLibrariesMap =
+      new HashMap<Source, List<Source>>();
+
+  /**
    * Initialize a newly created manager.
    */
   DartWorkManager(this.context);
@@ -99,6 +112,14 @@
     // library queue
     librarySourceQueue.removeAll(changedSources);
     librarySourceQueue.removeAll(removedSources);
+    // parts in libraries
+    for (Source changedSource in changedSources) {
+      _onLibrarySourceChangedOrRemoved(changedSource);
+    }
+    for (Source removedSource in removedSources) {
+      partLibrariesMap.remove(removedSource);
+      _onLibrarySourceChangedOrRemoved(removedSource);
+    }
     // Some of the libraries might have been invalidated, reschedule them.
     {
       MapIterator<AnalysisTarget, CacheEntry> iterator =
@@ -163,6 +184,15 @@
     return new AnalysisErrorInfoImpl(errors, lineInfo);
   }
 
+  /**
+   * Returns libraries containing the given [part].
+   * Maybe empty, but not null.
+   */
+  List<Source> getLibrariesContainingPart(Source part) {
+    List<Source> libraries = partLibrariesMap[part];
+    return libraries != null ? libraries : Source.EMPTY_LIST;
+  }
+
   @override
   TargetedResult getNextResult() {
     // Try to find a priority result to compute.
@@ -213,6 +243,10 @@
     return WorkOrderPriority.NONE;
   }
 
+  void unitIncrementallyResolved(Source librarySource, Source unitSource) {
+    librarySourceQueue.add(librarySource);
+  }
+
   @override
   void resultsComputed(
       AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs) {
@@ -221,11 +255,27 @@
       SourceKind kind = outputs[SOURCE_KIND];
       if (kind != null) {
         unknownSourceQueue.remove(target);
-        if (kind == SourceKind.LIBRARY) {
+        if (kind == SourceKind.LIBRARY &&
+            context.shouldErrorsBeAnalyzed(target, null)) {
           librarySourceQueue.add(target);
         }
       }
     }
+    // Update parts in libraries.
+    if (_isDartSource(target)) {
+      Source library = target;
+      List<Source> includedParts = outputs[INCLUDED_PARTS];
+      if (includedParts != null) {
+        libraryPartsMap[library] = includedParts;
+        for (Source part in includedParts) {
+          List<Source> libraries =
+              partLibrariesMap.putIfAbsent(part, () => <Source>[]);
+          if (!libraries.contains(library)) {
+            libraries.add(library);
+          }
+        }
+      }
+    }
     // Update notice.
     if (_isDartSource(target)) {
       bool shouldSetErrors = false;
@@ -234,7 +284,7 @@
           context.getNotice(target).parsedDartUnit = value;
           shouldSetErrors = true;
         }
-        if (_isErrorResult(descriptor)) {
+        if (descriptor == DART_ERRORS) {
           shouldSetErrors = true;
         }
       });
@@ -251,9 +301,6 @@
           context.getNotice(source).resolvedDartUnit = value;
           shouldSetErrors = true;
         }
-        if (_isErrorResult(descriptor)) {
-          shouldSetErrors = true;
-        }
       });
       if (shouldSetErrors) {
         AnalysisErrorInfo info = getErrors(source);
@@ -271,12 +318,23 @@
     return state != CacheState.VALID && state != CacheState.ERROR;
   }
 
-  static bool _isDartSource(AnalysisTarget target) {
-    return target is Source && AnalysisEngine.isDartFileName(target.fullName);
+  /**
+   * The given [library] source was changed or removed.
+   * Update [libraryPartsMap] and [partLibrariesMap].
+   */
+  void _onLibrarySourceChangedOrRemoved(Source library) {
+    List<Source> parts = libraryPartsMap.remove(library);
+    if (parts != null) {
+      for (Source part in parts) {
+        List<Source> libraries = partLibrariesMap[part];
+        if (libraries != null) {
+          libraries.remove(library);
+        }
+      }
+    }
   }
 
-  static bool _isErrorResult(ResultDescriptor descriptor) {
-    return _SOURCE_ERRORS.contains(descriptor) ||
-        _UNIT_ERRORS.contains(descriptor);
+  static bool _isDartSource(AnalysisTarget target) {
+    return target is Source && AnalysisEngine.isDartFileName(target.fullName);
   }
 }
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index 0cff292..87929c0 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -149,7 +149,7 @@
     }
     try {
       TaskDescriptor taskDescriptor = taskManager.findTask(target, result);
-      WorkItem workItem = new WorkItem(context, target, taskDescriptor);
+      WorkItem workItem = new WorkItem(context, target, taskDescriptor, result);
       return new WorkOrder(taskManager, workItem);
     } catch (exception, stackTrace) {
       throw new AnalysisException(
@@ -348,10 +348,12 @@
    * it.  The client is expected to evaluate this component before calling
    * [getNextStronglyConnectedComponent] again.
    */
-  List<Node> getNextStronglyConnectedComponent() {
+  StronglyConnectedComponent<Node> getNextStronglyConnectedComponent() {
     while (_currentIndices.isNotEmpty) {
       Node nextUnevaluatedInput = getNextInput(_path[_currentIndices.last],
           _provisionalDependencies[_currentIndices.last]);
+      assert(!_provisionalDependencies[_currentIndices.last]
+          .contains(nextUnevaluatedInput));
       if (nextUnevaluatedInput != null) {
         // TODO(paulberry): the call to _path.indexOf makes the algorithm
         // O(n^2) in the depth of the dependency graph.  If this becomes a
@@ -392,11 +394,17 @@
           // No more nodes in the current strongly connected component need to
           // have their indices examined.  We can now yield this component to
           // the caller.
-          List<Node> component = _path.sublist(_contractedPath.last);
+          List<Node> nodes = _path.sublist(_contractedPath.last);
+          bool containsCycle = nodes.length > 1;
+          if (!containsCycle) {
+            if (_provisionalDependencies.last.isNotEmpty) {
+              containsCycle = true;
+            }
+          }
           _path.length = _contractedPath.last;
           _provisionalDependencies.length = _contractedPath.last;
           _contractedPath.removeLast();
-          return component;
+          return new StronglyConnectedComponent<Node>(nodes, containsCycle);
         } else {
           // At least one node in the current strongly connected component
           // still needs to have its inputs examined.  So loop and allow the
@@ -428,11 +436,40 @@
  */
 class InfiniteTaskLoopException extends AnalysisException {
   /**
-   * Initialize a newly created exception to represent an attempt to perform
-   * the task for the target represented by the given [item].
+   * If a dependency cycle was found while computing the inputs for the task,
+   * the set of [WorkItem]s contained in the cycle (if there are overlapping
+   * cycles, this is the set of all [WorkItem]s in the entire strongly
+   * connected component).  Otherwise, `null`.
    */
-  InfiniteTaskLoopException(WorkItem item) : super(
-          'Infinite loop while performing task ${item.descriptor.name} for ${item.target}');
+  final List<WorkItem> dependencyCycle;
+
+  /**
+   * Initialize a newly created exception to represent a failed attempt to
+   * perform the given [task] due to the given [dependencyCycle].
+   */
+  InfiniteTaskLoopException(AnalysisTask task, this.dependencyCycle) : super(
+          'Infinite loop while performing task ${task.descriptor.name} for ${task.target}');
+}
+
+/**
+ * Object used by CycleAwareDependencyWalker to report a single strongly
+ * connected component of nodes.
+ */
+class StronglyConnectedComponent<Node> {
+  /**
+   * The nodes contained in the strongly connected component.
+   */
+  final List<Node> nodes;
+
+  /**
+   * Indicates whether the strongly component contains any cycles.  Note that
+   * if [nodes] has multiple elements, this will always be `true`.  However, if
+   * [nodes] has exactly one element, this may be either `true` or `false`
+   * depending on whether the node has a dependency on itself.
+   */
+  final bool containsCycle;
+
+  StronglyConnectedComponent(this.nodes, this.containsCycle);
 }
 
 /**
@@ -456,6 +493,11 @@
   final TaskDescriptor descriptor;
 
   /**
+   * The [ResultDescriptor] which was led to this work item being spawned.
+   */
+  final ResultDescriptor spawningResult;
+
+  /**
    * An iterator used to iterate over the descriptors of the inputs to the task,
    * or `null` if all of the inputs have been collected and the task can be
    * created.
@@ -482,10 +524,18 @@
   CaughtException exception = null;
 
   /**
+   * If a dependency cycle was found while computing the inputs for the task,
+   * the set of [WorkItem]s contained in the cycle (if there are overlapping
+   * cycles, this is the set of all [WorkItem]s in the entire strongly
+   * connected component).  Otherwise, `null`.
+   */
+  List<WorkItem> dependencyCycle;
+
+  /**
    * Initialize a newly created work item to compute the inputs for the task
    * described by the given descriptor.
    */
-  WorkItem(this.context, this.target, this.descriptor) {
+  WorkItem(this.context, this.target, this.descriptor, this.spawningResult) {
     AnalysisTarget actualTarget = identical(
             target, AnalysisContextTarget.request)
         ? new AnalysisContextTarget(context)
@@ -519,7 +569,9 @@
     if (builder != null) {
       throw new StateError("some inputs have not been computed");
     }
-    return descriptor.createTask(context, target, inputs);
+    AnalysisTask task = descriptor.createTask(context, target, inputs);
+    task.dependencyCycle = dependencyCycle;
+    return task;
   }
 
   /**
@@ -538,14 +590,19 @@
    * if the field is non-`null` then the task cannot be performed and all of the
    * tasks' results should be marked as being in ERROR.
    */
-  WorkItem gatherInputs(TaskManager taskManager) {
+  WorkItem gatherInputs(TaskManager taskManager, List<WorkItem> skipInputs) {
     while (builder != null) {
       AnalysisTarget inputTarget = builder.currentTarget;
       ResultDescriptor inputResult = builder.currentResult;
       inputTargetedResults.add(new TargetedResult(inputTarget, inputResult));
       CacheEntry inputEntry = context.getCacheEntry(inputTarget);
       CacheState inputState = inputEntry.getState(inputResult);
-      if (inputState == CacheState.ERROR) {
+      if (skipInputs.any((WorkItem item) =>
+          item.target == inputTarget && item.spawningResult == inputResult)) {
+        // This input is being skipped due to a circular dependency.  Tell the
+        // builder that it's not available so we can move on to other inputs.
+        builder.currentValueNotAvailable();
+      } else if (inputState == CacheState.ERROR) {
         exception = inputEntry.exception;
         return null;
       } else if (inputState == CacheState.IN_PROCESS) {
@@ -560,17 +617,19 @@
         // IN_PROCESS is CONTENT, I don't know that it's worth the extra effort
         // to implement the general solution at this point.
         //
+        throw new UnimplementedError();
       } else if (inputState != CacheState.VALID) {
         try {
           TaskDescriptor descriptor =
               taskManager.findTask(inputTarget, inputResult);
-          return new WorkItem(context, inputTarget, descriptor);
+          return new WorkItem(context, inputTarget, descriptor, inputResult);
         } on AnalysisException catch (exception, stackTrace) {
           this.exception = new CaughtException(exception, stackTrace);
           return null;
         }
+      } else {
+        builder.currentValue = inputEntry.getValue(inputResult);
       }
-      builder.currentValue = inputEntry.getValue(inputResult);
       if (!builder.moveNext()) {
         inputs = builder.inputValue;
         builder = null;
@@ -584,31 +643,6 @@
 }
 
 /**
- * The priorities of work orders returned by [WorkManager]s.
- */
-enum WorkOrderPriority {
-  /**
-   * Responding to an user's action.
-   */
-  INTERACTIVE,
-
-  /**
-   * Computing information for priority sources.
-   */
-  PRIORITY,
-
-  /**
-   * A work should be done, but without any special urgency.
-   */
-  NORMAL,
-
-  /**
-   * Nothing to do.
-   */
-  NONE
-}
-
-/**
  * [AnalysisDriver] uses [WorkManager]s to select results to compute.
  *
  * They know specific of the targets and results they care about,
@@ -688,18 +722,17 @@
       return true;
     } else {
       // Get a new strongly connected component.
-      currentItems = _dependencyWalker.getNextStronglyConnectedComponent();
-      if (currentItems == null) {
+      StronglyConnectedComponent<WorkItem> nextStronglyConnectedComponent =
+          _dependencyWalker.getNextStronglyConnectedComponent();
+      if (nextStronglyConnectedComponent == null) {
+        currentItems = null;
         return false;
       }
-      if (currentItems.length > 1) {
+      currentItems = nextStronglyConnectedComponent.nodes;
+      if (nextStronglyConnectedComponent.containsCycle) {
         // A cycle has been found.
         for (WorkItem item in currentItems) {
-          try {
-            throw new InfiniteTaskLoopException(item);
-          } on InfiniteTaskLoopException catch (exception, stackTrace) {
-            item.exception = new CaughtException(exception, stackTrace);
-          }
+          item.dependencyCycle = currentItems.toList();
         }
       } else {
         assert(currentItems.length == 1);
@@ -710,6 +743,31 @@
 }
 
 /**
+ * The priorities of work orders returned by [WorkManager]s.
+ */
+enum WorkOrderPriority {
+  /**
+   * Responding to an user's action.
+   */
+  INTERACTIVE,
+
+  /**
+   * Computing information for priority sources.
+   */
+  PRIORITY,
+
+  /**
+   * A work should be done, but without any special urgency.
+   */
+  NORMAL,
+
+  /**
+   * Nothing to do.
+   */
+  NONE
+}
+
+/**
  * Specilaization of [CycleAwareDependencyWalker] for use by [WorkOrder].
  */
 class _WorkOrderDependencyWalker extends CycleAwareDependencyWalker<WorkItem> {
@@ -723,11 +781,6 @@
 
   @override
   WorkItem getNextInput(WorkItem node, List<WorkItem> skipInputs) {
-    if (skipInputs.isNotEmpty) {
-      // TODO(paulberry): this is a hack.  We assume that an analysis loop has
-      // been found, so we don't try to compute anything else.
-      return null;
-    }
-    return node.gatherInputs(taskManager);
+    return node.gatherInputs(taskManager, skipInputs);
   }
 }
diff --git a/pkg/analyzer/lib/src/task/inputs.dart b/pkg/analyzer/lib/src/task/inputs.dart
index 27b48c5..3ff506b 100644
--- a/pkg/analyzer/lib/src/task/inputs.dart
+++ b/pkg/analyzer/lib/src/task/inputs.dart
@@ -236,6 +236,15 @@
   }
 
   @override
+  void currentValueNotAvailable() {
+    if (currentBuilder == null) {
+      throw new StateError(
+          'Cannot set the result value when there is no current result');
+    }
+    currentBuilder.currentValueNotAvailable();
+  }
+
+  @override
   bool moveNext() {
     // Prepare base Map.
     if (baseMap == null) {
@@ -243,6 +252,11 @@
         return true;
       }
       baseMap = currentBuilder.inputValue;
+      if (baseMap == null) {
+        // No base map could be computed due to a circular dependency.  Use an
+        // empty map so that no further results will be computed.
+        baseMap = {};
+      }
       keyIterator = baseMap.keys.iterator;
       // Done with this builder.
       currentBuilder = null;
@@ -254,7 +268,9 @@
       }
       // Add the result value for the current Map key/value.
       E resultValue = currentBuilder.inputValue;
-      inputValue.add(resultValue);
+      if (resultValue != null) {
+        inputValue.add(resultValue);
+      }
       // Done with this builder.
       currentBuilder = null;
     }
@@ -329,7 +345,8 @@
   final SimpleTaskInput<V> input;
 
   /**
-   * The value of the input being built.
+   * The value of the input being built.  `null` if the value hasn't been set
+   * yet, or if no result is available ([currentValueNotAvailable] was called).
    */
   V _resultValue = null;
 
@@ -374,6 +391,16 @@
   }
 
   @override
+  void currentValueNotAvailable() {
+    if (_state != _AT) {
+      throw new StateError(
+          'Cannot set the result value when there is no current result');
+    }
+    _resultValue = null;
+    _resultSet = true;
+  }
+
+  @override
   bool moveNext() {
     if (_state == _BEFORE) {
       _state = _AT;
@@ -470,6 +497,15 @@
   String get _currentName => inputNames[nameIndex];
 
   @override
+  void currentValueNotAvailable() {
+    if (currentBuilder == null) {
+      throw new StateError(
+          'Cannot set the result value when there is no current result');
+    }
+    currentBuilder.currentValueNotAvailable();
+  }
+
+  @override
   bool moveNext() {
     if (nameIndex >= inputNames.length) {
       // We have already computed all of the results, so just return false.
@@ -485,7 +521,9 @@
         // current name.
         return true;
       }
-      inputs[_currentName] = currentBuilder.inputValue;
+      if (currentBuilder.inputValue != null) {
+        inputs[_currentName] = currentBuilder.inputValue;
+      }
       nameIndex++;
     }
     if (nameIndex >= inputNames.length) {
@@ -605,6 +643,15 @@
   C get _resultValue;
 
   @override
+  void currentValueNotAvailable() {
+    if (currentBuilder == null) {
+      throw new StateError(
+          'Cannot set the result value when there is no current result');
+    }
+    currentBuilder.currentValueNotAvailable();
+  }
+
+  @override
   bool moveNext() {
     if (currentBuilder == null) {
       if (_resultValue == null) {
@@ -624,11 +671,18 @@
       // We have finished computing the list of values from which the results
       // will be derived.
       _baseList = currentBuilder.inputValue;
+      if (_baseList == null) {
+        // No base list could be computed due to a circular dependency.  Use an
+        // empty list so that no further results will be computed.
+        _baseList = [];
+      }
       _baseListIndex = 0;
       _initResultValue();
     } else {
       // We have finished computing one of the elements in the result list.
-      _addResultElement(_baseListElement, currentBuilder.inputValue);
+      if (currentBuilder.inputValue != null) {
+        _addResultElement(_baseListElement, currentBuilder.inputValue);
+      }
       _baseListIndex++;
     }
     if (_baseListIndex >= _baseList.length) {
diff --git a/pkg/analyzer/lib/src/task/model.dart b/pkg/analyzer/lib/src/task/model.dart
index a48f85a..9ef568e 100644
--- a/pkg/analyzer/lib/src/task/model.dart
+++ b/pkg/analyzer/lib/src/task/model.dart
@@ -37,6 +37,11 @@
  * A concrete implementation of a [ResultDescriptor].
  */
 class ResultDescriptorImpl<V> implements ResultDescriptor<V> {
+  static int _NEXT_HASH = 0;
+
+  @override
+  final hashCode = _NEXT_HASH++;
+
   /**
    * The name of the result, used for debugging.
    */
@@ -61,6 +66,11 @@
       {this.cachingPolicy: DEFAULT_CACHING_POLICY});
 
   @override
+  bool operator ==(Object other) {
+    return other is ResultDescriptorImpl && other.hashCode == hashCode;
+  }
+
+  @override
   TaskInput<V> of(AnalysisTarget target) =>
       new SimpleTaskInput<V>(target, this);
 
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/task/model.dart
index 8f65f8b..15ff9fc 100644
--- a/pkg/analyzer/lib/task/model.dart
+++ b/pkg/analyzer/lib/task/model.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/model.dart';
 
 /**
@@ -116,6 +117,14 @@
   CaughtException caughtException;
 
   /**
+   * If a dependency cycle was found while computing the inputs for the task,
+   * the set of [WorkItem]s contained in the cycle (if there are overlapping
+   * cycles, this is the set of all [WorkItem]s in the entire strongly
+   * connected component).  Otherwise, `null`.
+   */
+  List<WorkItem> dependencyCycle;
+
+  /**
    * Initialize a newly created task to perform analysis within the given
    * [context] in order to produce results for the given [target].
    */
@@ -132,6 +141,14 @@
   TaskDescriptor get descriptor;
 
   /**
+   * Indicates whether the task is capable of handling dependency cycles.  A
+   * task that overrides this getter to return `true` must be prepared for the
+   * possibility that it will be invoked with a non-`null` value of
+   * [dependencyCycle], and with not all of its inputs computed.
+   */
+  bool get handlesDependencyCycles => false;
+
+  /**
    * Return the value of the input with the given [name]. Throw an exception if
    * the input value is not defined.
    */
@@ -203,7 +220,7 @@
         contextName = 'unnamed';
       }
       AnalysisEngine.instance.instrumentationService.logAnalysisTask(
-          contextName, description);
+          contextName, this);
       //
       // Gather statistics on the performance of the task.
       //
@@ -219,6 +236,9 @@
       // Actually perform the task.
       //
       try {
+        if (dependencyCycle != null && !handlesDependencyCycles) {
+          throw new InfiniteTaskLoopException(this, dependencyCycle);
+        }
         internalPerform();
       } finally {
         stopwatch.stop();
@@ -461,10 +481,21 @@
    *
    * Throws a [StateError] if [moveNext] has not been invoked or if the last
    * invocation of [moveNext] returned `true`.
+   *
+   * Returns `null` if no value could be computed due to a circular dependency.
    */
   V get inputValue;
 
   /**
+   * Record that no value is available for the current result, due to a
+   * circular dependency.
+   *
+   * Throws a [StateError] if [moveNext] has not been invoked or if the last
+   * invocation of [moveNext] returned `false`.
+   */
+  void currentValueNotAvailable();
+
+  /**
    * Move to the next result that needs to be computed in order to build the
    * inputs for a task. Return `true` if there is another result that needs to
    * be computed, or `false` if the inputs have been computed.
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index ea3dd0c..2b8ca78 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,13 +1,14 @@
 name: analyzer
-version: 0.25.0+1
+version: 0.25.1-alpha.0
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
 environment:
   sdk: '>=0.8.10+6 <2.0.0'
 dependencies:
+  args: <0.14.0
   path: '>=0.9.0 <2.0.0'
-  plugin: '<0.2.0'
+  plugin: <0.2.0
   watcher: '>=0.9.0 <0.10.0'
 dev_dependencies:
   typed_mock: '>=0.0.4 <1.0.0'
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index d56a925..4937cc8 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -34,7 +34,7 @@
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/task/dart.dart';
-import 'package:path/src/context.dart';
+import 'package:path/path.dart';
 import 'package:unittest/unittest.dart';
 
 import '../reflective_tests.dart';
@@ -2506,7 +2506,8 @@
   }
 
   NonExistingSource _dummySource() {
-    return new NonExistingSource("foo.dart", UriKind.FILE_URI);
+    String path = '/test.dart';
+    return new NonExistingSource(path, toUri(path), UriKind.FILE_URI);
   }
 
   DartObjectImpl _evaluateConstant(CompilationUnit compilationUnit, String name,
@@ -6629,8 +6630,8 @@
     ImportElementImpl element =
         ElementFactory.importFor(ElementFactory.library(null, ''), null);
     GatheringErrorListener listener = new GatheringErrorListener();
-    ErrorReporter reporter = new ErrorReporter(
-        listener, new NonExistingSource("/test.dart", UriKind.FILE_URI));
+    ErrorReporter reporter = new ErrorReporter(listener, new NonExistingSource(
+        '/test.dart', toUri('/test.dart'), UriKind.FILE_URI));
     reporter.reportErrorForElement(
         StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER,
         element, ['A']);
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 3f6b77c..abea165 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -4685,6 +4685,16 @@
     verify([source]);
   }
 
+  void test_recursiveCompileTimeConstant_singleVariable() {
+    Source source = addSource(r'''
+const x = x;
+''');
+    resolve(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT]);
+    verify([source]);
+  }
+
   void test_recursiveConstructorRedirect() {
     Source source = addSource(r'''
 class A {
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 19269a4..f6e60396 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -35,6 +35,7 @@
 import 'package:analyzer/src/string_source.dart';
 import 'package:analyzer/src/task/task_dart.dart';
 import 'package:analyzer/task/model.dart' hide AnalysisTask;
+import 'package:path/path.dart' as pathos;
 import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
 import 'package:watcher/src/utils.dart';
@@ -5727,6 +5728,10 @@
     return false;
   }
   @override
+  void invalidateLibraryHints(Source librarySource) {
+    fail("Unexpected invocation of invalidateLibraryHints");
+  }
+  @override
   bool isClientLibrary(Source librarySource) {
     fail("Unexpected invocation of isClientLibrary");
     return false;
@@ -5793,6 +5798,11 @@
   }
 
   @override
+  bool shouldErrorsBeAnalyzed(Source source, Object entry) {
+    fail("Unexpected invocation of shouldErrorsBeAnalyzed");
+    return false;
+  }
+  @override
   void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
       DataDescriptor rowDesc, CacheState state)) {
     fail("Unexpected invocation of visitCacheItems");
@@ -6587,7 +6597,7 @@
 
 class _Source_getContent_throwException extends NonExistingSource {
   _Source_getContent_throwException(String name)
-      : super(name, UriKind.FILE_URI);
+      : super(name, pathos.toUri(name), UriKind.FILE_URI);
 
   @override
   TimestampedData<String> get contents {
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 9d8ccce..0e8d130 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -2758,6 +2758,7 @@
     int updateEndOld = updateOffset + edit.length;
     int updateOldNew = updateOffset + edit.replacement.length;
     IncrementalResolver resolver = new IncrementalResolver(
+        analysisContext2.getReadableSourceEntryOrNull(source), null, null,
         unit.element, updateOffset, updateEndOld, updateOldNew);
     bool success = resolver.resolve(newNode);
     expect(success, isTrue);
diff --git a/pkg/analyzer/test/source/package_map_resolver_test.dart b/pkg/analyzer/test/source/package_map_resolver_test.dart
index e4b0bb6..c892947 100644
--- a/pkg/analyzer/test/source/package_map_resolver_test.dart
+++ b/pkg/analyzer/test/source/package_map_resolver_test.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:path/path.dart';
 import 'package:unittest/unittest.dart';
 
 import '../reflective_tests.dart';
@@ -144,7 +145,8 @@
     Source result = resolver.resolveAbsolute(uri);
     expect(result, isNotNull);
     expect(result.exists(), isFalse);
-    expect(result.fullName, 'package:analyzer/analyzer.dart');
+    expect(result.fullName, 'analyzer.dart');
+    expect(result.uri.toString(), 'package:analyzer/analyzer.dart');
   }
 
   void test_restoreAbsolute() {
@@ -229,6 +231,6 @@
   }
 
   Source _createFileSource(String path) {
-    return new NonExistingSource(path, UriKind.FILE_URI);
+    return new NonExistingSource(path, toUri(path), UriKind.FILE_URI);
   }
 }
diff --git a/pkg/analyzer/test/src/context/abstract_context.dart b/pkg/analyzer/test/src/context/abstract_context.dart
index 8e7b555..a4a374f 100644
--- a/pkg/analyzer/test/src/context/abstract_context.dart
+++ b/pkg/analyzer/test/src/context/abstract_context.dart
@@ -6,27 +6,25 @@
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart'
-    hide AnalysisContextImpl, AnalysisTask;
+    hide AnalysisCache, AnalysisContextImpl, AnalysisTask;
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/plugin/engine_plugin.dart';
-import 'package:plugin/manager.dart';
+import 'package:analyzer/src/task/driver.dart';
 import 'package:unittest/unittest.dart';
 
 import 'mock_sdk.dart';
-import 'package:analyzer/src/task/driver.dart';
 
 class AbstractContextTest {
   MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
 
-  ExtensionManager extensionManager = new ExtensionManager();
-
   DartSdk sdk = new MockSdk();
   SourceFactory sourceFactory;
   AnalysisContextImpl context;
+  AnalysisCache analysisCache;
   AnalysisDriver analysisDriver;
 
   Source addSource(String path, String contents) {
@@ -85,13 +83,6 @@
   }
 
   void setUp() {
-    // configure TaskManager
-    {
-      EnginePlugin plugin = AnalysisEngine.instance.enginePlugin;
-      if (plugin.taskExtensionPoint == null) {
-        extensionManager.processPlugins([plugin]);
-      }
-    }
     // prepare AnalysisContext
     sourceFactory = new SourceFactory(<UriResolver>[
       new DartUriResolver(sdk),
@@ -99,6 +90,7 @@
     ]);
     context = createAnalysisContext();
     context.sourceFactory = sourceFactory;
+    analysisCache = context.analysisCache;
     analysisDriver = context.driver;
   }
 
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index f093931..80f8166 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -67,6 +67,33 @@
     expect(cache.getContextFor(target), context);
   }
 
+  void test_getSourcesWithFullName() {
+    String filePath = '/foo/lib/file.dart';
+    // no sources
+    expect(cache.getSourcesWithFullName(filePath), isEmpty);
+    // add source1
+    TestSourceWithUri source1 =
+        new TestSourceWithUri(filePath, Uri.parse('file://$filePath'));
+    cache.put(new CacheEntry(source1));
+    expect(cache.getSourcesWithFullName(filePath), unorderedEquals([source1]));
+    // add source2
+    TestSourceWithUri source2 =
+        new TestSourceWithUri(filePath, Uri.parse('package:foo/file.dart'));
+    cache.put(new CacheEntry(source2));
+    expect(cache.getSourcesWithFullName(filePath),
+        unorderedEquals([source1, source2]));
+    // remove source1
+    cache.remove(source1);
+    expect(cache.getSourcesWithFullName(filePath), unorderedEquals([source2]));
+    // remove source2
+    cache.remove(source2);
+    expect(cache.getSourcesWithFullName(filePath), isEmpty);
+    // ignored
+    cache.remove(source1);
+    cache.remove(source2);
+    expect(cache.getSourcesWithFullName(filePath), isEmpty);
+  }
+
   void test_getState_hasEntry_flushed() {
     ResultDescriptor result = new ResultDescriptor('result', -1);
     AnalysisTarget target = new TestSource();
@@ -183,6 +210,29 @@
     }
     expect(cache.size(), size);
   }
+
+  void test_sources() {
+    AnalysisTarget source1 = new TestSource('1.dart');
+    AnalysisTarget source2 = new TestSource('2.dart');
+    AnalysisTarget target1 = new _TestAnalysisTarget();
+    // no entries
+    expect(cache.sources, isEmpty);
+    // add source1
+    cache.put(new CacheEntry(source1));
+    expect(cache.sources, unorderedEquals([source1]));
+    // add target1
+    cache.put(new CacheEntry(target1));
+    expect(cache.sources, unorderedEquals([source1]));
+    // add source2
+    cache.put(new CacheEntry(source2));
+    expect(cache.sources, unorderedEquals([source1, source2]));
+    // remove source1
+    cache.remove(source1);
+    expect(cache.sources, unorderedEquals([source2]));
+    // remove source2
+    cache.remove(source2);
+    expect(cache.sources, isEmpty);
+  }
 }
 
 @reflectiveTest
@@ -574,6 +624,35 @@
     expect(entry.getValue(result2), 222);
   }
 
+  test_setValueIncremental() {
+    AnalysisTarget target = new TestSource();
+    CacheEntry entry = new CacheEntry(target);
+    cache.put(entry);
+    ResultDescriptor result1 = new ResultDescriptor('result1', -1);
+    ResultDescriptor result2 = new ResultDescriptor('result2', -2);
+    ResultDescriptor result3 = new ResultDescriptor('result3', -3);
+    // set results, all of them are VALID
+    entry.setValue(result1, 111, TargetedResult.EMPTY_LIST);
+    entry.setValue(result2, 222, [new TargetedResult(target, result1)]);
+    entry.setValue(result3, 333, [new TargetedResult(target, result2)]);
+    expect(entry.getState(result1), CacheState.VALID);
+    expect(entry.getState(result2), CacheState.VALID);
+    expect(entry.getState(result3), CacheState.VALID);
+    expect(entry.getValue(result1), 111);
+    expect(entry.getValue(result2), 222);
+    expect(entry.getValue(result3), 333);
+    // replace result1, keep "dependedOn", invalidate result3
+    entry.setValueIncremental(result2, 2222);
+    expect(entry.getState(result1), CacheState.VALID);
+    expect(entry.getState(result2), CacheState.VALID);
+    expect(entry.getState(result3), CacheState.INVALID);
+    expect(entry.getValue(result1), 111);
+    expect(entry.getValue(result2), 2222);
+    expect(entry.getValue(result3), -3);
+    expect(entry.getResultData(result2).dependedOnResults,
+        unorderedEquals([new TargetedResult(target, result1)]));
+  }
+
   test_toString_empty() {
     AnalysisTarget target = new TestSource();
     CacheEntry entry = new CacheEntry(target);
@@ -648,6 +727,24 @@
     expect(manager.recentlyUsed, orderedEquals([result1, result3, result2]));
   }
 
+  test_resultAccessed_negativeMaxSize() {
+    manager = new CacheFlushManager(new SimpleResultCachingPolicy(-1, -1),
+        (AnalysisTarget target) => false);
+    ResultDescriptor descriptor1 = new ResultDescriptor('result1', null);
+    ResultDescriptor descriptor2 = new ResultDescriptor('result2', null);
+    AnalysisTarget target = new TestSource();
+    TargetedResult result1 = new TargetedResult(target, descriptor1);
+    TargetedResult result2 = new TargetedResult(target, descriptor2);
+    manager.resultStored(result1, null);
+    manager.resultStored(result2, null);
+    expect(manager.currentSize, 0);
+    expect(manager.recentlyUsed, isEmpty);
+    // access result2
+    manager.resultAccessed(result2);
+    expect(manager.currentSize, 0);
+    expect(manager.recentlyUsed, isEmpty);
+  }
+
   test_resultAccessed_noSuchResult() {
     ResultDescriptor descriptor1 = new ResultDescriptor('result1', null);
     ResultDescriptor descriptor2 = new ResultDescriptor('result2', null);
@@ -698,6 +795,20 @@
     }
   }
 
+  test_resultStored_negativeMaxSize() {
+    manager = new CacheFlushManager(new SimpleResultCachingPolicy(-1, -1),
+        (AnalysisTarget target) => false);
+    ResultDescriptor descriptor1 = new ResultDescriptor('result1', null);
+    ResultDescriptor descriptor2 = new ResultDescriptor('result2', null);
+    AnalysisTarget target = new TestSource();
+    TargetedResult result1 = new TargetedResult(target, descriptor1);
+    TargetedResult result2 = new TargetedResult(target, descriptor2);
+    manager.resultStored(result1, null);
+    manager.resultStored(result2, null);
+    expect(manager.currentSize, 0);
+    expect(manager.recentlyUsed, isEmpty);
+  }
+
   test_targetRemoved() {
     ResultDescriptor descriptor1 = new ResultDescriptor('result1', null);
     ResultDescriptor descriptor2 = new ResultDescriptor('result2', null);
@@ -842,3 +953,8 @@
     implements InternalAnalysisContext {
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
+
+class _TestAnalysisTarget implements AnalysisTarget {
+  @override
+  Source get source => null;
+}
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index d799f1d..f1116d8 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -35,6 +35,7 @@
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/task/dart.dart';
+import 'package:path/path.dart' as pathos;
 import 'package:unittest/unittest.dart';
 import 'package:watcher/src/utils.dart';
 
@@ -2126,7 +2127,7 @@
 
 class _Source_getContent_throwException extends NonExistingSource {
   _Source_getContent_throwException(String name)
-      : super(name, UriKind.FILE_URI);
+      : super(name, pathos.toUri(name), UriKind.FILE_URI);
 
   @override
   TimestampedData<String> get contents {
diff --git a/pkg/analyzer/test/src/mock_sdk.dart b/pkg/analyzer/test/src/mock_sdk.dart
index 7cadfcc..1487f4a 100644
--- a/pkg/analyzer/test/src/mock_sdk.dart
+++ b/pkg/analyzer/test/src/mock_sdk.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/file_system/file_system.dart' as resource;
 import 'package:analyzer/file_system/memory_file_system.dart' as resource;
+import 'package:analyzer/src/context/context.dart' as newContext;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -188,7 +189,11 @@
   @override
   AnalysisContext get context {
     if (_analysisContext == null) {
-      _analysisContext = new SdkAnalysisContext();
+      if (AnalysisEngine.instance.useTaskModel) {
+        _analysisContext = new newContext.SdkAnalysisContext();
+      } else {
+        _analysisContext = new SdkAnalysisContext();
+      }
       SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
       _analysisContext.sourceFactory = factory;
       ChangeSet changeSet = new ChangeSet();
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 8e3882c..d5abbbf 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart' show CacheState;
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -162,6 +163,7 @@
 @reflectiveTest
 class BuildCompilationUnitElementTaskTest extends _AbstractDartTaskTest {
   Source source;
+  LibrarySpecificUnit target;
 
   test_buildInputs() {
     LibrarySpecificUnit target =
@@ -244,9 +246,28 @@
     expect(outputs[COMPILATION_UNIT_CONSTANTS], isNotNull);
   }
 
+  test_perform_reuseElement() {
+    _performBuildTask(r'''
+library lib;
+class A {}
+class B = Object with A;
+''');
+    CompilationUnit unit = outputs[RESOLVED_UNIT1];
+    CompilationUnitElement unitElement = outputs[COMPILATION_UNIT_ELEMENT];
+    expect(unit, isNotNull);
+    expect(unitElement, isNotNull);
+    // invalidate RESOLVED_UNIT1
+    CacheEntry cacheEntry = analysisCache.get(target);
+    cacheEntry.setState(RESOLVED_UNIT1, CacheState.INVALID);
+    // compute again
+    _computeResult(target, RESOLVED_UNIT1);
+    expect(outputs[COMPILATION_UNIT_ELEMENT], same(unitElement));
+    expect(outputs[RESOLVED_UNIT1], isNot(same(unit)));
+  }
+
   void _performBuildTask(String content) {
     source = newSource('/test.dart', content);
-    AnalysisTarget target = new LibrarySpecificUnit(source, source);
+    target = new LibrarySpecificUnit(source, source);
     _computeResult(target, RESOLVED_UNIT1);
     expect(task, new isInstanceOf<BuildCompilationUnitElementTask>());
   }
@@ -1312,18 +1333,26 @@
     return null;
   }
 
-  fail_circular_reference() {
-    // TODO(paulberry): get this to work.
-    EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
-        'x', '''
-const x = y + 1;
-const y = x + 1;
+  test_annotation_non_const_constructor() {
+    // Calling a non-const constructor from an annotation that is illegal, but
+    // shouldn't crash analysis.
+    Source source = newSource('/test.dart', '''
+class A {
+  final int i;
+  A(this.i);
+}
+
+@A(5)
+class C {}
 ''');
+    // First compute the resolved unit for the source.
+    CompilationUnit unit = _resolveSource(source);
+    // Compute the constant value of the annotation on C.
+    EvaluationResultImpl evaluationResult =
+        computeClassAnnotation(source, unit, 'C');
+    // And check that it has no value stored in it.
     expect(evaluationResult, isNotNull);
     expect(evaluationResult.value, isNull);
-    expect(evaluationResult.errors, hasLength(1));
-    expect(evaluationResult.errors[0].errorCode,
-        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT);
   }
 
   test_annotation_with_args() {
@@ -1336,10 +1365,7 @@
 }
 ''');
     // First compute the resolved unit for the source.
-    LibrarySpecificUnit librarySpecificUnit =
-        new LibrarySpecificUnit(source, source);
-    _computeResult(librarySpecificUnit, RESOLVED_UNIT1);
-    CompilationUnit unit = outputs[RESOLVED_UNIT1];
+    CompilationUnit unit = _resolveSource(source);
     // Compute the constant value of the annotation on C.
     EvaluationResultImpl evaluationResult =
         computeClassAnnotation(source, unit, 'C');
@@ -1358,10 +1384,7 @@
 @x class C {}
 ''');
     // First compute the resolved unit for the source.
-    LibrarySpecificUnit librarySpecificUnit =
-        new LibrarySpecificUnit(source, source);
-    _computeResult(librarySpecificUnit, RESOLVED_UNIT1);
-    CompilationUnit unit = outputs[RESOLVED_UNIT1];
+    CompilationUnit unit = _resolveSource(source);
     // Compute the constant value of the annotation on C.
     EvaluationResultImpl evaluationResult =
         computeClassAnnotation(source, unit, 'C');
@@ -1371,6 +1394,29 @@
     expect(evaluationResult.value.intValue, 1);
   }
 
+  test_circular_reference() {
+    _checkCircularities('x', ['y'], '''
+const x = y + 1;
+const y = x + 1;
+''');
+  }
+
+  test_circular_reference_one_element() {
+    // See dartbug.com/23490.
+    _checkCircularities('x', [], 'const x = x;');
+  }
+
+  test_circular_reference_strongly_connected_component() {
+    // When there is a circularity, all elements in the strongly connected
+    // component should be marked as having an error.
+    _checkCircularities('a', ['b', 'c', 'd'], '''
+const a = b;
+const b = c + d;
+const c = a;
+const d = a;
+''');
+  }
+
   test_dependency() {
     EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
         'x', '''
@@ -1382,6 +1428,20 @@
     expect(evaluationResult.value.intValue, 2);
   }
 
+  test_external_const_factory() {
+    EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
+        'x', '''
+const x = const C.foo();
+
+class C extends B {
+  external const factory C.foo();
+}
+
+class B {}
+''');
+    expect(evaluationResult, isNotNull);
+  }
+
   test_simple_constant() {
     EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
         'x', '''
@@ -1392,20 +1452,30 @@
     expect(evaluationResult.value.intValue, 1);
   }
 
+  void _checkCircularities(
+      String variableName, List<String> otherVariables, String content) {
+    // Evaluating the first constant should produce an error.
+    CompilationUnit unit = _resolveUnit(content);
+    _expectCircularityError(_evaluateConstant(unit, variableName));
+    // And all the other constants involved in the strongly connected component
+    // should be set to the same error state.
+    for (String otherVariableName in otherVariables) {
+      PropertyInducingElement otherVariableElement =
+          _findVariable(unit, otherVariableName);
+      _expectCircularityError(
+          (otherVariableElement as TopLevelVariableElementImpl).evaluationResult);
+    }
+  }
+
   EvaluationResultImpl _computeTopLevelVariableConstValue(
       String variableName, String content) {
-    Source source = newSource('/test.dart', content);
-    // First compute the resolved unit for the source.
-    LibrarySpecificUnit librarySpecificUnit =
-        new LibrarySpecificUnit(source, source);
-    _computeResult(librarySpecificUnit, RESOLVED_UNIT1);
-    CompilationUnit unit = outputs[RESOLVED_UNIT1];
+    return _evaluateConstant(_resolveUnit(content), variableName);
+  }
+
+  EvaluationResultImpl _evaluateConstant(
+      CompilationUnit unit, String variableName) {
     // Find the element for the given constant.
-    List<PropertyAccessorElement> accessors = unit.element.accessors;
-    Element variableElement = accessors
-        .firstWhere((PropertyAccessorElement accessor) {
-      return accessor.isGetter && accessor.name == variableName;
-    }).variable;
+    PropertyInducingElement variableElement = _findVariable(unit, variableName);
     // Now compute the value of the constant.
     _computeResult(variableElement, CONSTANT_VALUE);
     expect(outputs[CONSTANT_VALUE], same(variableElement));
@@ -1413,6 +1483,32 @@
         (variableElement as TopLevelVariableElementImpl).evaluationResult;
     return evaluationResult;
   }
+
+  void _expectCircularityError(EvaluationResultImpl evaluationResult) {
+    expect(evaluationResult, isNotNull);
+    expect(evaluationResult.value, isNull);
+    expect(evaluationResult.errors, hasLength(1));
+    expect(evaluationResult.errors[0].errorCode,
+        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT);
+  }
+
+  PropertyInducingElement _findVariable(
+      CompilationUnit unit, String variableName) {
+    // Find the element for the given constant.
+    return unit.element.topLevelVariables.firstWhere(
+        (TopLevelVariableElement variable) => variable.name == variableName);
+  }
+
+  CompilationUnit _resolveSource(Source source) {
+    LibrarySpecificUnit librarySpecificUnit =
+        new LibrarySpecificUnit(source, source);
+    _computeResult(librarySpecificUnit, RESOLVED_UNIT1);
+    CompilationUnit unit = outputs[RESOLVED_UNIT1];
+    return unit;
+  }
+
+  CompilationUnit _resolveUnit(String content) =>
+      _resolveSource(newSource('/test.dart', content));
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/task/dart_work_manager_test.dart b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
index 9872011..c5dc211 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -132,6 +132,85 @@
     expect_librarySourceQueue([source1, source3]);
   }
 
+  void test_applyChange_updatePartsLibraries_changeLibrary() {
+    Source part1 = new TestSource('part1.dart');
+    Source part2 = new TestSource('part2.dart');
+    Source part3 = new TestSource('part3.dart');
+    Source library1 = new TestSource('library1.dart');
+    Source library2 = new TestSource('library2.dart');
+    manager.partLibrariesMap[part1] = [library1, library2];
+    manager.partLibrariesMap[part2] = [library2];
+    manager.partLibrariesMap[part3] = [library1];
+    manager.libraryPartsMap[library1] = [part1, part3];
+    manager.libraryPartsMap[library2] = [part1, part2];
+    // change library1
+    manager.applyChange([], [library1], []);
+    expect(manager.partLibrariesMap[part1], unorderedEquals([library2]));
+    expect(manager.partLibrariesMap[part2], unorderedEquals([library2]));
+    expect(manager.partLibrariesMap[part3], unorderedEquals([]));
+    expect(manager.libraryPartsMap[library1], isNull);
+    expect(manager.libraryPartsMap[library2], [part1, part2]);
+  }
+
+  void test_applyChange_updatePartsLibraries_changePart() {
+    Source part1 = new TestSource('part1.dart');
+    Source part2 = new TestSource('part2.dart');
+    Source part3 = new TestSource('part3.dart');
+    Source library1 = new TestSource('library1.dart');
+    Source library2 = new TestSource('library2.dart');
+    manager.partLibrariesMap[part1] = [library1, library2];
+    manager.partLibrariesMap[part2] = [library2];
+    manager.partLibrariesMap[part3] = [library1];
+    manager.libraryPartsMap[library1] = [part1, part3];
+    manager.libraryPartsMap[library2] = [part1, part2];
+    // change part1
+    manager.applyChange([], [part1], []);
+    expect(manager.partLibrariesMap[part2], unorderedEquals([library2]));
+    expect(manager.partLibrariesMap[part3], unorderedEquals([library1]));
+    expect(manager.libraryPartsMap[library1], [part1, part3]);
+    expect(manager.libraryPartsMap[library2], [part1, part2]);
+  }
+
+  void test_applyChange_updatePartsLibraries_removeLibrary() {
+    Source part1 = new TestSource('part1.dart');
+    Source part2 = new TestSource('part2.dart');
+    Source part3 = new TestSource('part3.dart');
+    Source library1 = new TestSource('library1.dart');
+    Source library2 = new TestSource('library2.dart');
+    manager.partLibrariesMap[part1] = [library1, library2];
+    manager.partLibrariesMap[part2] = [library2];
+    manager.partLibrariesMap[part3] = [library1];
+    manager.libraryPartsMap[library1] = [part1, part3];
+    manager.libraryPartsMap[library2] = [part1, part2];
+    // remove library1
+    manager.applyChange([], [], [library1]);
+    expect(manager.partLibrariesMap[part1], unorderedEquals([library2]));
+    expect(manager.partLibrariesMap[part2], unorderedEquals([library2]));
+    expect(manager.partLibrariesMap[part3], unorderedEquals([]));
+    expect(manager.libraryPartsMap[library1], isNull);
+    expect(manager.libraryPartsMap[library2], [part1, part2]);
+  }
+
+  void test_applyChange_updatePartsLibraries_removePart() {
+    Source part1 = new TestSource('part1.dart');
+    Source part2 = new TestSource('part2.dart');
+    Source part3 = new TestSource('part3.dart');
+    Source library1 = new TestSource('library1.dart');
+    Source library2 = new TestSource('library2.dart');
+    manager.partLibrariesMap[part1] = [library1, library2];
+    manager.partLibrariesMap[part2] = [library2];
+    manager.partLibrariesMap[part3] = [library1];
+    manager.libraryPartsMap[library1] = [part1, part3];
+    manager.libraryPartsMap[library2] = [part1, part2];
+    // remove part1
+    manager.applyChange([], [], [part1]);
+    expect(manager.partLibrariesMap[part1], isNull);
+    expect(manager.partLibrariesMap[part2], unorderedEquals([library2]));
+    expect(manager.partLibrariesMap[part3], unorderedEquals([library1]));
+    expect(manager.libraryPartsMap[library1], [part1, part3]);
+    expect(manager.libraryPartsMap[library2], [part1, part2]);
+  }
+
   void test_applyPriorityTargets_library() {
     entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
     entry2.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
@@ -186,6 +265,24 @@
     expect(errorInfo.lineInfo, lineInfo);
   }
 
+  void test_getLibrariesContainingPart() {
+    Source part1 = new TestSource('part1.dart');
+    Source part2 = new TestSource('part2.dart');
+    Source part3 = new TestSource('part3.dart');
+    Source library1 = new TestSource('library1.dart');
+    Source library2 = new TestSource('library2.dart');
+    manager.partLibrariesMap[part1] = [library1, library2];
+    manager.partLibrariesMap[part2] = [library2];
+    manager.libraryPartsMap[library1] = [part1];
+    manager.libraryPartsMap[library2] = [part1, part2];
+    // getLibrariesContainingPart
+    expect(manager.getLibrariesContainingPart(part1),
+        unorderedEquals([library1, library2]));
+    expect(
+        manager.getLibrariesContainingPart(part2), unorderedEquals([library2]));
+    expect(manager.getLibrariesContainingPart(part3), isEmpty);
+  }
+
   void test_getNextResult_hasLibraries_firstIsError() {
     entry1.setErrorState(caughtException, [LIBRARY_ERRORS_READY]);
     manager.librarySourceQueue.addAll([source1, source2]);
@@ -318,8 +415,9 @@
     AnalysisTarget unitTarget = new LibrarySpecificUnit(source2, source1);
     context.getCacheEntry(unitTarget).setValue(
         VERIFY_ERRORS, <AnalysisError>[error2], []);
-    // notify about LibrarySpecificUnit specific errors
-    manager.resultsComputed(unitTarget, {VERIFY_ERRORS: []});
+    // RESOLVED_UNIT is ready, set errors
+    manager.resultsComputed(
+        unitTarget, {RESOLVED_UNIT: AstFactory.compilationUnit()});
     // all of the errors are included
     ChangeNoticeImpl notice = context.getNotice(source1);
     expect(notice.errors, unorderedEquals([error1, error2]));
@@ -335,17 +433,38 @@
     LineInfo lineInfo = new LineInfo([0]);
     entry1.setValue(LINE_INFO, lineInfo, []);
     entry1.setValue(SCAN_ERRORS, <AnalysisError>[error1], []);
-    AnalysisTarget unitTarget = new LibrarySpecificUnit(source2, source1);
-    context.getCacheEntry(unitTarget).setValue(
-        VERIFY_ERRORS, <AnalysisError>[error2], []);
-    // notify about Source specific errors
-    manager.resultsComputed(source1, {SCAN_ERRORS: []});
+    entry1.setValue(PARSE_ERRORS, <AnalysisError>[error2], []);
+    // PARSED_UNIT is ready, set errors
+    manager.resultsComputed(
+        source1, {PARSED_UNIT: AstFactory.compilationUnit()});
     // all of the errors are included
     ChangeNoticeImpl notice = context.getNotice(source1);
     expect(notice.errors, unorderedEquals([error1, error2]));
     expect(notice.lineInfo, lineInfo);
   }
 
+  void test_resultsComputed_includedParts() {
+    Source part1 = new TestSource('part1.dart');
+    Source part2 = new TestSource('part2.dart');
+    Source part3 = new TestSource('part3.dart');
+    Source library1 = new TestSource('library1.dart');
+    Source library2 = new TestSource('library2.dart');
+    // library1 parts
+    manager.resultsComputed(library1, {INCLUDED_PARTS: [part1, part2]});
+    expect(manager.partLibrariesMap[part1], [library1]);
+    expect(manager.partLibrariesMap[part2], [library1]);
+    expect(manager.partLibrariesMap[part3], isNull);
+    expect(manager.libraryPartsMap[library1], [part1, part2]);
+    expect(manager.libraryPartsMap[library2], isNull);
+    // library2 parts
+    manager.resultsComputed(library2, {INCLUDED_PARTS: [part2, part3]});
+    expect(manager.partLibrariesMap[part1], [library1]);
+    expect(manager.partLibrariesMap[part2], [library1, library2]);
+    expect(manager.partLibrariesMap[part3], [library2]);
+    expect(manager.libraryPartsMap[library1], [part1, part2]);
+    expect(manager.libraryPartsMap[library2], [part2, part3]);
+  }
+
   void test_resultsComputed_noSourceKind() {
     manager.unknownSourceQueue.addAll([source1, source2]);
     manager.resultsComputed(source1, {});
@@ -387,6 +506,7 @@
 
   void test_resultsComputed_sourceKind_isLibrary() {
     manager.unknownSourceQueue.addAll([source1, source2, source3]);
+    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
     manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
     expect_librarySourceQueue([source2]);
     expect_unknownSourceQueue([source1, source3]);
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index 3b92fbf..cfbbe81 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -213,7 +213,54 @@
     expect(analysisDriver.performAnalysisTask(), false);
   }
 
-  test_performAnalysisTask_infiniteLoop() {
+  test_performAnalysisTask_infiniteLoop_handled() {
+    AnalysisTarget target = new TestSource();
+    ResultDescriptor resultA = new ResultDescriptor('resultA', -1);
+    ResultDescriptor resultB = new ResultDescriptor('resultB', -2);
+    // configure tasks
+    TestAnalysisTask task1;
+    TestAnalysisTask task2;
+    TaskDescriptor descriptor1 = new TaskDescriptor('task1',
+        (context, target) => task1, (target) => {
+      'inputB': new SimpleTaskInput<int>(target, resultB)
+    }, [resultA]);
+    TaskDescriptor descriptor2 = new TaskDescriptor('task2',
+        (context, target) => task2, (target) => {
+      'inputA': new SimpleTaskInput<int>(target, resultA)
+    }, [resultB]);
+    task1 = new TestAnalysisTask(context, target,
+        descriptor: descriptor1,
+        results: [resultA],
+        value: 10,
+        handlesDependencyCycles: true);
+    task2 = new TestAnalysisTask(context, target,
+        descriptor: descriptor2,
+        results: [resultB],
+        value: 20,
+        handlesDependencyCycles: true);
+    taskManager.addTaskDescriptor(descriptor1);
+    taskManager.addTaskDescriptor(descriptor2);
+    // configure WorkManager
+    when(workManager1.getNextResultPriority()).thenReturnList(
+        <WorkOrderPriority>[WorkOrderPriority.NORMAL, WorkOrderPriority.NONE]);
+    when(workManager1.getNextResult())
+        .thenReturn(new TargetedResult(target, resultB));
+    // prepare work order
+    while (analysisDriver.performAnalysisTask()) {}
+    Set<TaskDescriptor> expectedCycle = [descriptor1, descriptor2].toSet();
+    expect(task1.dependencyCycle, isNotNull);
+    expect(task1.dependencyCycle.map((workItem) => workItem.descriptor).toSet(),
+        expectedCycle);
+    expect(task2.dependencyCycle, isNotNull);
+    expect(task2.dependencyCycle.map((workItem) => workItem.descriptor).toSet(),
+        expectedCycle);
+    CaughtException exception = context.getCacheEntry(target).exception;
+    expect(exception, isNull);
+    expect(context.getCacheEntry(target).getValue(resultA), 10);
+    expect(context.getCacheEntry(target).getValue(resultB), 20);
+  }
+
+  test_performAnalysisTask_infiniteLoop_unhandled() {
     AnalysisTarget target = new TestSource();
     ResultDescriptor resultA = new ResultDescriptor('resultA', -1);
     ResultDescriptor resultB = new ResultDescriptor('resultB', -2);
@@ -295,7 +342,7 @@
         'task', (context, target) => task, (target) => {}, [result]);
     task = new TestAnalysisTask(context, target,
         descriptor: descriptor, exception: exception);
-    WorkItem item = new WorkItem(context, target, descriptor);
+    WorkItem item = new WorkItem(context, target, descriptor, null);
 
     analysisDriver.performWorkItem(item);
     CacheEntry targetEntry = context.getCacheEntry(item.target);
@@ -310,7 +357,7 @@
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', (context, target) => task, (target) => {}, [result]);
     task = new TestAnalysisTask(context, target, descriptor: descriptor);
-    WorkItem item = new WorkItem(context, target, descriptor);
+    WorkItem item = new WorkItem(context, target, descriptor, null);
 
     analysisDriver.performWorkItem(item);
     CacheEntry targetEntry = context.getCacheEntry(item.target);
@@ -326,7 +373,7 @@
         (target) => {}, [result]);
     CaughtException exception =
         new CaughtException(new AnalysisException(), null);
-    WorkItem item = new WorkItem(context, target, descriptor);
+    WorkItem item = new WorkItem(context, target, descriptor, null);
     item.exception = exception;
 
     analysisDriver.performWorkItem(item);
@@ -342,7 +389,7 @@
         (target) => {'one': inputResult.of(target)},
         [new ResultDescriptor('output', null)]);
     analysisDriver.currentWorkOrder =
-        new WorkOrder(taskManager, new WorkItem(null, null, descriptor));
+        new WorkOrder(taskManager, new WorkItem(null, null, descriptor, null));
 
     analysisDriver.reset();
     expect(analysisDriver.currentWorkOrder, isNull);
@@ -407,23 +454,35 @@
 @reflectiveTest
 class CycleAwareDependencyWalkerTest {
   void checkGraph(Map<int, List<int>> graph, int startingNode,
-      List<List<int>> expectedResults) {
+      List<StronglyConnectedComponent<int>> expectedResults) {
     List<Set<int>> expectedResultsDisregardingOrder =
-        expectedResults.map((nodes) => nodes.toSet()).toList();
+        expectedResults.map((component) => component.nodes.toSet()).toList();
+    List<bool> expectedCycleIndicators =
+        expectedResults.map((component) => component.containsCycle).toList();
     List<Set<int>> results = <Set<int>>[];
+    List<bool> cycleIndicators = <bool>[];
     _TestCycleAwareDependencyWalker walker =
         new _TestCycleAwareDependencyWalker(graph, startingNode);
     while (true) {
-      List<int> nextResult = walker.getNextStronglyConnectedComponent();
-      if (nextResult == null) {
+      StronglyConnectedComponent<int> nextStronglyConnectedComponent =
+          walker.getNextStronglyConnectedComponent();
+      if (nextStronglyConnectedComponent == null) {
         break;
       }
-      results.add(nextResult.toSet());
-      walker.evaluatedNodes.addAll(nextResult);
+      results.add(nextStronglyConnectedComponent.nodes.toSet());
+      cycleIndicators.add(nextStronglyConnectedComponent.containsCycle);
+      walker.evaluatedNodes.addAll(nextStronglyConnectedComponent.nodes);
     }
     expect(results, expectedResultsDisregardingOrder);
+    expect(cycleIndicators, expectedCycleIndicators);
   }
 
+  StronglyConnectedComponent<int> cycle(List<int> nodes) =>
+      new StronglyConnectedComponent(nodes, true);
+
+  StronglyConnectedComponent<int> singleton(int node) =>
+      new StronglyConnectedComponent(<int>[node], false);
+
   void test_complex_graph() {
     checkGraph({
       1: [2, 3],
@@ -432,27 +491,35 @@
       4: [3, 5],
       5: [2, 6],
       6: [3, 4]
-    }, 1, [[3], [2, 4, 5, 6], [1]]);
+    }, 1, [singleton(3), cycle([2, 4, 5, 6]), singleton(1)]);
   }
 
   void test_cycle_depends_on_other_nodes() {
-    checkGraph({1: [2, 3], 2: [4, 1], 3: [], 4: []}, 1, [[4], [3], [1, 2]]);
+    checkGraph({1: [2, 3], 2: [4, 1], 3: [], 4: []}, 1, [
+      singleton(4),
+      singleton(3),
+      cycle([1, 2])
+    ]);
   }
 
   void test_initial_node_depends_on_cycle() {
-    checkGraph({1: [2], 2: [3], 3: [2]}, 1, [[2, 3], [1]]);
+    checkGraph({1: [2], 2: [3], 3: [2]}, 1, [cycle([2, 3]), singleton(1)]);
   }
 
   void test_simple_cycle() {
-    checkGraph({1: [2], 2: [1]}, 1, [[1, 2]]);
+    checkGraph({1: [2], 2: [1]}, 1, [cycle([1, 2])]);
   }
 
   void test_simple_dependency_chain() {
-    checkGraph({1: [2], 2: []}, 1, [[2], [1]]);
+    checkGraph({1: [2], 2: []}, 1, [singleton(2), singleton(1)]);
   }
 
   void test_single_node() {
-    checkGraph({1: []}, 1, [[1]]);
+    checkGraph({1: []}, 1, [singleton(1)]);
+  }
+
+  void test_single_node_cycle() {
+    checkGraph({1: [1]}, 1, [cycle([1])]);
   }
 }
 
@@ -463,7 +530,7 @@
     TaskDescriptor descriptor = new TaskDescriptor('task',
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {}, [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor);
+    WorkItem item = new WorkItem(context, target, descriptor, null);
     AnalysisTask task = item.buildTask();
     expect(task, isNotNull);
   }
@@ -476,7 +543,7 @@
     TaskDescriptor descriptor = new TaskDescriptor('task', (context, target) =>
             new TestAnalysisTask(context, target, results: outputResults),
         (target) => {'one': inputResult.of(target)}, outputResults);
-    WorkItem item = new WorkItem(context, target, descriptor);
+    WorkItem item = new WorkItem(context, target, descriptor, null);
     expect(() => item.buildTask(), throwsStateError);
   }
 
@@ -484,7 +551,7 @@
     AnalysisTarget target = new TestSource();
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (target) => {}, [new ResultDescriptor('result', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor);
+    WorkItem item = new WorkItem(context, target, descriptor, null);
     expect(item, isNotNull);
     expect(item.context, context);
     expect(item.descriptor, descriptor);
@@ -496,8 +563,8 @@
     TaskDescriptor descriptor = new TaskDescriptor('task',
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {}, [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor);
-    WorkItem result = item.gatherInputs(taskManager);
+    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem result = item.gatherInputs(taskManager, []);
     expect(result, isNull);
     expect(item.exception, isNull);
   }
@@ -516,8 +583,8 @@
     taskManager.addTaskDescriptor(task1);
     taskManager.addTaskDescriptor(task2);
     // gather inputs
-    WorkItem item = new WorkItem(context, target, task2);
-    WorkItem inputItem = item.gatherInputs(taskManager);
+    WorkItem item = new WorkItem(context, target, task2, null);
+    WorkItem inputItem = item.gatherInputs(taskManager, []);
     expect(inputItem, isNotNull);
   }
 
@@ -528,8 +595,8 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {'one': inputResult.of(target)},
         [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor);
-    WorkItem result = item.gatherInputs(taskManager);
+    WorkItem item = new WorkItem(context, target, descriptor, null);
+    WorkItem result = item.gatherInputs(taskManager, []);
     expect(result, isNull);
     expect(item.exception, isNotNull);
   }
@@ -542,7 +609,7 @@
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
     WorkOrder order =
-        new WorkOrder(manager, new WorkItem(null, null, descriptor));
+        new WorkOrder(manager, new WorkItem(null, null, descriptor, null));
     expect(order, isNotNull);
     expect(order.currentItems, isNull);
     expect(order.current, isNull);
@@ -552,7 +619,7 @@
     TaskManager manager = new TaskManager();
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
-    WorkItem workItem = new WorkItem(null, null, descriptor);
+    WorkItem workItem = new WorkItem(null, null, descriptor, null);
     WorkOrder order = new WorkOrder(manager, workItem);
     // "item" has no child items
     expect(order.moveNext(), isTrue);
diff --git a/pkg/analyzer/test/src/task/inputs_test.dart b/pkg/analyzer/test/src/task/inputs_test.dart
index f894d11..4c4c6a4 100644
--- a/pkg/analyzer/test/src/task/inputs_test.dart
+++ b/pkg/analyzer/test/src/task/inputs_test.dart
@@ -95,6 +95,14 @@
     expect(builder.currentResult, null);
   }
 
+  test_currentResult_afterCurrentValueNotAvailable() {
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+    builder.moveNext();
+    expect(builder.currentResult, null);
+  }
+
   test_currentResult_afterOneMoveNext() {
     ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     builder.moveNext();
@@ -114,6 +122,14 @@
     expect(builder.currentTarget, null);
   }
 
+  test_currentTarget_afterCurrentValueNotAvailable() {
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+    builder.moveNext();
+    expect(builder.currentTarget, null);
+  }
+
   test_currentTarget_afterOneMoveNext() {
     ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     builder.moveNext();
@@ -138,6 +154,19 @@
     }, throwsStateError);
   }
 
+  test_currentValueNotAvailable_afterOneMoveNext() {
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+  }
+
+  test_currentValueNotAvailable_beforeMoveNext() {
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
+    expect(() {
+      builder.currentValueNotAvailable();
+    }, throwsStateError);
+  }
+
   test_inputValue_afterComplete() {
     AnalysisTarget target2 = new TestSource();
     AnalysisTarget target3 = new TestSource();
@@ -159,6 +188,35 @@
     expect(list[1], value3);
   }
 
+  test_inputValue_afterFirstValueNotAvailable() {
+    AnalysisTarget target2 = new TestSource();
+    AnalysisTarget target3 = new TestSource();
+    String value3 = 'value3';
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
+    builder.moveNext(); // Advance to requesting the list
+    builder.currentValue = [target2, target3];
+    builder.moveNext(); // Advance to requesting result2 for target2
+    builder.currentValueNotAvailable();
+    builder.moveNext(); // Advance to requesting result2 for target3
+    builder.currentValue = value3;
+    builder.moveNext(); // Advance to the end
+    var inputValue = builder.inputValue;
+    expect(inputValue, new isInstanceOf<List>());
+    List list = inputValue;
+    expect(list, orderedEquals([value3]));
+  }
+
+  test_inputValue_afterListNotAvailable() {
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
+    builder.moveNext(); // Advance to requesting the list
+    builder.currentValueNotAvailable();
+    builder.moveNext(); // Advance to the end
+    var inputValue = builder.inputValue;
+    expect(inputValue, new isInstanceOf<List>());
+    List list = inputValue;
+    expect(list, isEmpty);
+  }
+
   test_inputValue_afterOneMoveNext() {
     ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     builder.moveNext();
@@ -232,6 +290,14 @@
     expect(builder.currentResult, null);
   }
 
+  test_currentResult_afterCurrentValueNotAvailable() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+    builder.moveNext();
+    expect(builder.currentResult, null);
+  }
+
   test_currentResult_afterOneMoveNext() {
     ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
     builder.moveNext();
@@ -251,6 +317,14 @@
     expect(builder.currentTarget, null);
   }
 
+  test_currentTarget_afterCurrentValueNotAvailable() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+    builder.moveNext();
+    expect(builder.currentTarget, null);
+  }
+
   test_currentTarget_afterOneMoveNext() {
     ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
     builder.moveNext();
@@ -275,6 +349,19 @@
     }, throwsStateError);
   }
 
+  test_currentValueNotAvailable_afterOneMoveNext() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+  }
+
+  test_currentValueNotAvailable_beforeMoveNext() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    expect(() {
+      builder.currentValueNotAvailable();
+    }, throwsStateError);
+  }
+
   test_inputValue_afterComplete() {
     AnalysisTarget target2 = new TestSource('target2');
     AnalysisTarget target3 = new TestSource('target3');
@@ -295,6 +382,34 @@
     expect(inputValue, containsPair(target3, value3));
   }
 
+  test_inputValue_afterFirstValueNotAvailable() {
+    AnalysisTarget target2 = new TestSource('target2');
+    AnalysisTarget target3 = new TestSource('target3');
+    String value3 = 'value3';
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext(); // Advance to requesting the list
+    builder.currentValue = [target2, target3];
+    builder.moveNext(); // Advance to requesting result2 for target2
+    builder.currentValueNotAvailable();
+    builder.moveNext(); // Advance to requesting result2 for target3
+    builder.currentValue = value3;
+    builder.moveNext(); // Advance to the end
+    var inputValue = builder.inputValue;
+    expect(inputValue, new isInstanceOf<Map>());
+    expect(inputValue, hasLength(1));
+    expect(inputValue, containsPair(target3, value3));
+  }
+
+  test_inputValue_afterListNotAvailable() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext(); // Advance to requesting the list
+    builder.currentValueNotAvailable();
+    builder.moveNext(); // Advance to the end
+    var inputValue = builder.inputValue;
+    expect(inputValue, new isInstanceOf<Map>());
+    expect(inputValue, isEmpty);
+  }
+
   test_inputValue_afterOneMoveNext() {
     ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
     builder.moveNext();
@@ -365,6 +480,14 @@
     expect(builder.currentResult, null);
   }
 
+  test_currentResult_afterCurrentValueNotAvailable() {
+    SimpleTaskInputBuilder builder = new SimpleTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+    builder.moveNext();
+    expect(builder.currentResult, null);
+  }
+
   test_currentResult_afterOneMoveNext() {
     SimpleTaskInputBuilder builder = new SimpleTaskInputBuilder(input);
     builder.moveNext();
@@ -384,6 +507,14 @@
     expect(builder.currentTarget, null);
   }
 
+  test_currentTarget_afterCurrentValueNotAvailable() {
+    SimpleTaskInputBuilder builder = new SimpleTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+    builder.moveNext();
+    expect(builder.currentTarget, null);
+  }
+
   test_currentTarget_afterOneMoveNext() {
     SimpleTaskInputBuilder builder = new SimpleTaskInputBuilder(input);
     builder.moveNext();
@@ -408,6 +539,19 @@
     }, throwsStateError);
   }
 
+  test_currentValueNotAvailable_afterOneMoveNext() {
+    SimpleTaskInputBuilder builder = new SimpleTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+  }
+
+  test_currentValueNotAvailable_beforeMoveNext() {
+    SimpleTaskInputBuilder builder = new SimpleTaskInputBuilder(input);
+    expect(() {
+      builder.currentValueNotAvailable();
+    }, throwsStateError);
+  }
+
   test_inputValue_afterComplete() {
     SimpleTaskInputBuilder builder = new SimpleTaskInputBuilder(input);
     builder.moveNext();
@@ -417,6 +561,15 @@
     expect(builder.inputValue, value);
   }
 
+  test_inputValue_afterCurrentValueNotAvailable() {
+    SimpleTaskInputBuilder builder = new SimpleTaskInputBuilder(input);
+    builder.moveNext();
+    String value = 'value';
+    builder.currentValueNotAvailable();
+    builder.moveNext();
+    expect(builder.inputValue, isNull);
+  }
+
   test_inputValue_afterOneMoveNext() {
     SimpleTaskInputBuilder builder = new SimpleTaskInputBuilder(input);
     builder.moveNext();
@@ -490,6 +643,16 @@
     expect(builder.currentResult, null);
   }
 
+  test_currentResult_afterCurrentValueNotAvailable() {
+    Map<String, TaskInput> inputDescriptors = {'one': input1};
+    TopLevelTaskInputBuilder builder =
+        new TopLevelTaskInputBuilder(inputDescriptors);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+    builder.moveNext();
+    expect(builder.currentResult, null);
+  }
+
   test_currentResult_afterOneMoveNext() {
     Map<String, TaskInput> inputDescriptors = {'one': input1, 'two': input2};
     TopLevelTaskInputBuilder builder =
@@ -515,6 +678,16 @@
     expect(builder.currentTarget, null);
   }
 
+  test_currentTarget_afterCurrentValueNotAvailable() {
+    Map<String, TaskInput> inputDescriptors = {'one': input1};
+    TopLevelTaskInputBuilder builder =
+        new TopLevelTaskInputBuilder(inputDescriptors);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+    builder.moveNext();
+    expect(builder.currentTarget, null);
+  }
+
   test_currentTarget_afterOneMoveNext() {
     Map<String, TaskInput> inputDescriptors = {'one': input1};
     TopLevelTaskInputBuilder builder =
@@ -547,6 +720,23 @@
     }, throwsStateError);
   }
 
+  test_currentValueNotAvailable_afterOneMoveNext() {
+    Map<String, TaskInput> inputDescriptors = {'one': input1};
+    TopLevelTaskInputBuilder builder =
+        new TopLevelTaskInputBuilder(inputDescriptors);
+    builder.moveNext();
+    builder.currentValueNotAvailable();
+  }
+
+  test_currentValueNotAvailable_beforeMoveNext() {
+    Map<String, TaskInput> inputDescriptors = {'one': input1};
+    TopLevelTaskInputBuilder builder =
+        new TopLevelTaskInputBuilder(inputDescriptors);
+    expect(() {
+      builder.currentValueNotAvailable();
+    }, throwsStateError);
+  }
+
   test_inputValue_afterComplete() {
     String key1 = 'one';
     String key2 = 'two';
@@ -576,6 +766,25 @@
     expect(() => builder.inputValue, throwsStateError);
   }
 
+  test_inputValue_afterOneValueNotAvailable() {
+    String key1 = 'one';
+    String key2 = 'two';
+    String value2 = 'value2';
+    Map<String, TaskInput> inputDescriptors = {key1: input1, key2: input2};
+    TopLevelTaskInputBuilder builder =
+        new TopLevelTaskInputBuilder(inputDescriptors);
+    builder.moveNext(); // Advance to requesting result1 for target
+    builder.currentValueNotAvailable();
+    builder.moveNext(); // Advance to requesting result2 for target
+    builder.currentValue = value2;
+    builder.moveNext(); // Advance to the end
+    var inputValue = builder.inputValue;
+    expect(inputValue, new isInstanceOf<Map>());
+    Map inputs = inputValue;
+    expect(inputs, hasLength(1));
+    expect(inputs, containsPair(key2, value2));
+  }
+
   test_inputValue_beforeMoveNext() {
     Map<String, TaskInput> inputDescriptors = {};
     TopLevelTaskInputBuilder builder =
diff --git a/pkg/analyzer/test/src/task/test_support.dart b/pkg/analyzer/test/src/task/test_support.dart
index 80cd7c3..2173ba2 100644
--- a/pkg/analyzer/test/src/task/test_support.dart
+++ b/pkg/analyzer/test/src/task/test_support.dart
@@ -32,8 +32,12 @@
    */
   int value;
 
+  @override
+  final bool handlesDependencyCycles;
+
   TestAnalysisTask(AnalysisContext context, AnalysisTarget target,
-      {this.descriptor, this.exception, this.results, this.value: 1})
+      {this.descriptor, this.exception, this.handlesDependencyCycles: false,
+      this.results, this.value: 1})
       : super(context, target);
 
   @override
diff --git a/pkg/analyzer2dart/lib/src/cps_generator.dart b/pkg/analyzer2dart/lib/src/cps_generator.dart
index 24a5eb2..8bd4c0a 100644
--- a/pkg/analyzer2dart/lib/src/cps_generator.dart
+++ b/pkg/analyzer2dart/lib/src/cps_generator.dart
@@ -412,7 +412,7 @@
     // [TreeShaker] and shared with the [CpsGeneratingVisitor].

     assert(invariant(node, target.isTopLevel || target.isStatic,

                      '$target expected to be top-level or static.'));

-    return irBuilder.buildStaticFieldGet(target);

+    return irBuilder.buildStaticFieldLazyGet(target, null);

   }

 

   ir.Primitive handleBinaryExpression(BinaryExpression node,

diff --git a/pkg/analyzer2dart/lib/src/modely.dart b/pkg/analyzer2dart/lib/src/modely.dart
index b386d5a..e865675 100644
--- a/pkg/analyzer2dart/lib/src/modely.dart
+++ b/pkg/analyzer2dart/lib/src/modely.dart
@@ -655,7 +655,7 @@
   lookupMember(String memberName) => unsupported('lookupMember');
 
   @override
-  lookupSelector(selector) => unsupported('lookupSelector');
+  lookupByName(dart2js.Name  memberName) => unsupported('lookupByName');
 
   @override
   lookupSuperMember(String memberName) => unsupported('lookupSuperMember');
@@ -666,7 +666,8 @@
   }
 
   @override
-  lookupSuperSelector(selector) => unsupported('lookupSuperSelector');
+  lookupSuperByName(dart2js.Name memberName) =>
+      unsupported('lookupSuperByName');
 
   @override
   String get nativeTagInfo => unsupported('nativeTagInfo');
diff --git a/pkg/analyzer2dart/test/sexpr_data.dart b/pkg/analyzer2dart/test/sexpr_data.dart
index d4d89d0..e7d00ae 100644
--- a/pkg/analyzer2dart/test/sexpr_data.dart
+++ b/pkg/analyzer2dart/test/sexpr_data.dart
@@ -1066,7 +1066,7 @@
 (FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
-    (TypeOperator is a String k0)))
+    (TypeOperator is a String () k0)))
 '''),
 
     const TestSpec('''
@@ -1077,7 +1077,7 @@
 (FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
-    (TypeOperator is a List<String> k0)))
+    (TypeOperator is a List<String> () k0)))
 '''),
 
     const TestSpec('''
@@ -1088,7 +1088,7 @@
 (FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
-    (TypeOperator is a Comparator<String> k0)))
+    (TypeOperator is a Comparator<String> () k0)))
 '''),
 
   const TestSpec('''
@@ -1107,7 +1107,7 @@
             (LetPrim (v3 (Constant (Bool true)))
               (InvokeContinuation k1 (v3)))))
           (Branch (IsTrue v0) k2 k3)))))
-    (TypeOperator is a String k0)))
+    (TypeOperator is a String () k0)))
 '''),
 
 const TestSpec('''
@@ -1118,7 +1118,7 @@
 (FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
-    (TypeOperator as a String k0)))
+    (TypeOperator as a String () k0)))
 '''),
   ]),
 
@@ -1298,8 +1298,9 @@
 ''', const {
       'main': '''
 (FunctionDefinition main () (args) return
-  (LetPrim (v0 (GetStatic field))
-    (InvokeContinuation return (v0))))
+  (LetCont ((k0 (v0)
+      (InvokeContinuation return (v0))))
+    (GetLazyStatic field k0)))
 ''',
       'field': '''
 (FieldDefinition field)
@@ -1313,8 +1314,9 @@
 ''', const {
       'main': '''
 (FunctionDefinition main () (args) return
-  (LetPrim (v0 (GetStatic field))
-    (InvokeContinuation return (v0))))
+  (LetCont ((k0 (v0)
+      (InvokeContinuation return (v0))))
+    (GetLazyStatic field k0)))
 ''',
       'field': '''
 (FieldDefinition field () return
@@ -1330,8 +1332,9 @@
 ''', const {
       'main': '''
 (FunctionDefinition main () (args) return
-  (LetPrim (v0 (GetStatic field))
-    (InvokeContinuation return (v0))))
+  (LetCont ((k0 (v0)
+      (InvokeContinuation return (v0))))
+    (GetLazyStatic field k0)))
 ''',
       'field': '''
 (FieldDefinition field () return
@@ -1349,8 +1352,9 @@
 (FunctionDefinition main () (args) return
   (LetCont ((k0 (v0)
       (SetStatic field v0
-        (LetPrim (v1 (GetStatic field))
-          (InvokeContinuation return (v1))))))
+        (LetCont ((k1 (v1)
+            (InvokeContinuation return (v1))))
+          (GetLazyStatic field k1)))))
     (InvokeMethod args length () k0)))
 '''),
   ]),
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index de680da..a9579f0 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -89,7 +89,9 @@
             generateCodeWithCompileTimeErrors:
                 hasOption(options, '--generate-code-with-compile-time-errors'),
             allowNativeExtensions:
-                hasOption(options, '--allow-native-extensions')) {
+                hasOption(options, '--allow-native-extensions'),
+            enableNullAwareOperators:
+                hasOption(options, '--enable-null-aware-operators')) {
     tasks.addAll([
         userHandlerTask = new leg.GenericTask('Diagnostic handler', this),
         userProviderTask = new leg.GenericTask('Input provider', this),
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 6d8b6d0..65d269c 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -781,6 +781,10 @@
   /// If `true` native extension syntax is supported by the frontend.
   final bool allowNativeExtensions;
 
+  /// Temporary flag to enable `?.`, `??`, and `??=` until it becomes part of
+  /// the spec.
+  final bool enableNullAwareOperators;
+
   /// Output provider from user of Compiler API.
   api.CompilerOutputProvider userOutputProvider;
 
@@ -909,7 +913,7 @@
       }
       hasCrashed = true;
       rethrow;
-    } on StackOverflowError catch (ex) {
+    } on StackOverflowError {
       // We cannot report anything useful in this case, because we
       // do not have enough stack space.
       rethrow;
@@ -1044,6 +1048,7 @@
             bool hasIncrementalSupport: false,
             this.enableExperimentalMirrors: false,
             this.allowNativeExtensions: false,
+            this.enableNullAwareOperators: false,
             this.generateCodeWithCompileTimeErrors: false,
             api.CompilerOutputProvider outputProvider,
             List<String> strips: const []})
@@ -1763,9 +1768,7 @@
         resolved.remove(e);
       }
       if (identical(e.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) {
-        ClassElement enclosingClass = e.enclosingClass;
         resolved.remove(e);
-
       }
       if (backend.isBackendLibrary(e.library)) {
         resolved.remove(e);
@@ -1901,7 +1904,6 @@
   void reportAssertionFailure(SpannableAssertionFailure ex) {
     String message = (ex.message != null) ? tryToString(ex.message)
                                           : tryToString(ex);
-    SourceSpan span = spanFromSpannable(ex.node);
     reportDiagnosticInternal(
         ex.node, MessageKind.GENERIC, {'text': message}, api.Diagnostic.CRASH);
   }
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index 18c323e..717bc06 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -466,6 +466,11 @@
   /// closure fields in order to access the receiver from the enclosing method.
   ir.Primitive buildThis();
 
+  /// Creates a type test or type cast of [value] against [type].
+  ir.Primitive buildTypeOperator(ir.Primitive value,
+                                 DartType type,
+                                 {bool isTypeTest});
+
   // TODO(johnniwinther): Make these field final and remove the default values
   // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin.
 
@@ -491,15 +496,8 @@
   }
 
   /// Creates a [ir.MutableVariable] for the given local.
-  void makeMutableVariable(Local local, [ClosureClassMap closureMap]) {
-    ExecutableElement owner;
-    if (closureMap == null || closureMap.closureClassElement == null) {
-      owner = local.executableContext;
-    } else {
-      assert(local.executableContext == closureMap.closureElement);
-      owner = closureMap.callElement;
-    }
-    mutableVariables[local] = new ir.MutableVariable(owner, local);
+  void makeMutableVariable(Local local) {
+    mutableVariables[local] = new ir.MutableVariable(local);
   }
 
   /// Remove an [ir.MutableVariable] for a local.
@@ -909,6 +907,12 @@
         state.localConstants, defaults);
   }
 
+  ir.FunctionDefinition makeLazyFieldInitializer() {
+    ir.Body body = makeBody();
+    FieldElement element = state.currentElement;
+    return new ir.FunctionDefinition(element, null, [], body, [], []);
+  }
+
   /// Create a invocation of the [method] on the super class where the call
   /// structure is defined [callStructure] and the argument values are defined
   /// by [arguments].
@@ -1084,10 +1088,18 @@
 
   /// Create a read access of the static [field].
   ir.Primitive buildStaticFieldGet(FieldElement field,
-                                   {SourceInformation sourceInformation}) {
+                                   SourceInformation sourceInformation) {
     return addPrimitive(new ir.GetStatic(field, sourceInformation));
   }
 
+  /// Create a read access of a static [field] that might not have been
+  /// initialized yet.
+  ir.Primitive buildStaticFieldLazyGet(FieldElement field,
+                                       SourceInformation sourceInformation) {
+    return _continueWithExpression(
+        (k) => new ir.GetLazyStatic(field, k, sourceInformation));
+  }
+
   /// Create a getter invocation of the static [getter].
   ir.Primitive buildStaticGetterGet(MethodElement getter,
                                     {SourceInformation sourceInformation}) {
@@ -1106,7 +1118,7 @@
   /// Create a write access to the static [field] with the [value].
   ir.Primitive buildStaticFieldSet(FieldElement field,
                                    ir.Primitive value,
-                                   {SourceInformation sourceInformation}) {
+                                   [SourceInformation sourceInformation]) {
     add(new ir.SetStatic(field, value, sourceInformation));
     return value;
   }
@@ -1751,7 +1763,7 @@
     for (LocalVariableElement variable in tryStatementInfo.boxedOnEntry) {
       assert(!tryCatchBuilder.isInMutableVariable(variable));
       ir.Primitive value = tryCatchBuilder.buildLocalVariableGet(variable);
-      tryCatchBuilder.makeMutableVariable(variable, closureClassMap);
+      tryCatchBuilder.makeMutableVariable(variable);
       tryCatchBuilder.declareLocalVariable(variable, initialValue: value);
     }
 
@@ -1836,23 +1848,25 @@
       ir.Continuation elseContinuation = new ir.Continuation([]);
       elseContinuation.body = catchBody;
 
-      ir.Parameter typeMatches = new ir.Parameter(null);
-      ir.Continuation checkType = new ir.Continuation([typeMatches]);
-      checkType.body =
-          new ir.LetCont.many([thenContinuation, elseContinuation],
-              new ir.Branch(new ir.IsTrue(typeMatches),
-                            thenContinuation,
-                            elseContinuation));
-      catchBody =
-          new ir.LetCont(checkType,
-              new ir.TypeOperator(exceptionParameter, clause.type, checkType,
-                                  isTypeTest: true));
+      // Build the type test guarding this clause. We can share the environment
+      // with the nested builder because this part cannot mutate it.
+      IrBuilder checkBuilder = catchBuilder.makeDelimitedBuilder(environment);
+      ir.Primitive typeMatches =
+          checkBuilder.buildTypeOperator(exceptionParameter,
+                                         clause.type,
+                                         isTypeTest: true);
+      checkBuilder.add(new ir.LetCont.many([thenContinuation, elseContinuation],
+                           new ir.Branch(new ir.IsTrue(typeMatches),
+                                         thenContinuation,
+                                         elseContinuation)));
+      catchBody = checkBuilder._root;
     }
 
     List<ir.Parameter> catchParameters =
         <ir.Parameter>[exceptionParameter, traceParameter];
     ir.Continuation catchContinuation = new ir.Continuation(catchParameters);
-    catchContinuation.body = catchBody;
+    catchBuilder.add(catchBody);
+    catchContinuation.body = catchBuilder._root;
 
     tryCatchBuilder.add(
         new ir.LetHandler(catchContinuation, tryBuilder._root));
@@ -1999,22 +2013,6 @@
     return resultParameter;
   }
 
-  /// Creates a type test or type cast of [receiver] against [type].
-  ///
-  /// Set [isTypeTest] to `true` to create a type test and furthermore set
-  /// [isNotCheck] to `true` to create a negated type test.
-  ir.Primitive buildTypeOperator(ir.Primitive receiver,
-                                 DartType type,
-                                 {bool isTypeTest: false,
-                                  bool isNotCheck: false}) {
-    assert(isOpen);
-    assert(isTypeTest != null);
-    assert(!isNotCheck || isTypeTest);
-    ir.Primitive check = _continueWithExpression(
-        (k) => new ir.TypeOperator(receiver, type, k, isTypeTest: isTypeTest));
-    return isNotCheck ? buildNegation(check) : check;
-  }
-
   /// Create a lazy and/or expression. [leftValue] is the value of the left
   /// operand and [buildRightValue] is called to process the value of the right
   /// operand in the context of its own [IrBuilder].
@@ -2300,6 +2298,18 @@
   ir.Primitive buildReifyTypeVariable(TypeVariableType variable) {
     return addPrimitive(new ir.ReifyTypeVar(variable.element));
   }
+
+  @override
+  ir.Primitive buildTypeOperator(ir.Primitive value,
+                                 DartType type,
+                                 {bool isTypeTest}) {
+    assert(isOpen);
+    assert(isTypeTest != null);
+    ir.Primitive check = _continueWithExpression(
+            (k) => new ir.TypeOperator(value, type,
+                       const <ir.Primitive>[], k, isTypeTest: isTypeTest));
+    return check;
+  }
 }
 
 /// State shared between JsIrBuilders within the same function.
@@ -2468,6 +2478,8 @@
                                             location.field);
       result.useElementAsHint(local);
       return addPrimitive(result);
+    } else if (isInMutableVariable(local)) {
+      return addPrimitive(new ir.GetMutableVariable(getMutableVariable(local)));
     } else {
       return environment.lookup(local);
     }
@@ -2483,6 +2495,8 @@
       add(new ir.SetField(environment.lookup(location.box),
                           location.field,
                           value));
+    } else if (isInMutableVariable(local)) {
+      add(new ir.SetMutableVariable(getMutableVariable(local), value));
     } else {
       value.useElementAsHint(local);
       environment.update(local, value);
@@ -2605,6 +2619,8 @@
         arguments.add(value);
       });
       return addPrimitive(new ir.TypeExpression(type, arguments));
+    } else if (type is DynamicType) {
+      return buildNullConstant();
     } else {
       // TypedefType can reach here, and possibly other things.
       throw 'unimplemented translation of type expression $type';
@@ -2647,6 +2663,35 @@
                                      List<ir.Primitive> arguments) {
     return addPrimitive(new ir.CreateInvocationMirror(selector, arguments));
   }
+
+  @override
+  ir.Primitive buildTypeOperator(ir.Primitive value,
+                                 DartType type,
+                                 {bool isTypeTest}) {
+    assert(isOpen);
+    assert(isTypeTest != null);
+    if (isTypeTest) {
+      // The TypeOperator node does not allow the Object, dynamic, and Null types,
+      // because the null value satisfies them. These must be handled here.
+      if (type.isObject || type.isDynamic) {
+        // `x is Object` and `x is dynamic` are always true, even if x is null.
+        return buildBooleanConstant(true);
+      }
+      if (type is InterfaceType && type.element == program.nullClass) {
+        // `x is Null` is true if and only if x is null.
+        return addPrimitive(new ir.Identical(value, buildNullConstant()));
+      }
+    }
+    // Null cannot not satisfy the check. Use a standard subtype check.
+    List<ir.Primitive> typeArguments = const <ir.Primitive>[];
+    if (type is GenericType && type.typeArguments.isNotEmpty) {
+      typeArguments = type.typeArguments.map(buildTypeExpression).toList();
+    }
+    ir.Primitive check = _continueWithExpression(
+            (k) => new ir.TypeOperator(value,
+                       type, typeArguments, k, isTypeTest: isTypeTest));
+    return check;
+  }
 }
 
 
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index c49953c..c603337 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -143,8 +143,9 @@
          BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>,
          BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>,
          BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>,
-         BaseImplementationOfSuperIncDecsMixin<ir.Primitive, dynamic>,
-         BaseImplementationOfNewMixin<ir.Primitive, dynamic>
+         BaseImplementationOfNewMixin<ir.Primitive, dynamic>,
+         BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>,
+         BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic>
     implements SemanticSendVisitor<ir.Primitive, dynamic> {
   final TreeElements elements;
   final Compiler compiler;
@@ -222,6 +223,9 @@
       CallStructure callStructure,
       List<ir.Primitive> arguments);
 
+  /// Read the value of [field].
+  ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src);
+
   /// Creates a [TypedSelector] variant of [newSelector] using the type of
   /// [oldSelector], if available.
   ///
@@ -755,14 +759,6 @@
   }
 
   @override
-  ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) {
-    return field.isConst
-        ? irBuilder.buildConstant(getConstantForVariable(field))
-        : irBuilder.buildStaticFieldGet(field,
-              sourceInformation: sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
   ir.Primitive handleStaticFunctionGet(
       ast.Send node,
       MethodElement function,
@@ -848,6 +844,12 @@
   }
 
   @override
+  ir.Primitive visitIfNull(
+      ast.Send node, ast.Node left, ast.Node right, _) {
+    internalError(node, "If-null not yet implemented in cps_ir");
+  }
+
+  @override
   ir.Primitive visitLogicalAnd(
       ast.Send node, ast.Node left, ast.Node right, _) {
     return translateLogicalOperator(left, right, isLazyOr: false);
@@ -875,21 +877,17 @@
       ast.Node expression,
       DartType type,
       _) {
-    ir.Primitive receiver = visit(expression);
-    return irBuilder.buildTypeOperator(
-        receiver, type,
-        isTypeTest: true,
-        isNotCheck: false);
+    ir.Primitive value = visit(expression);
+    return irBuilder.buildTypeOperator(value, type, isTypeTest: true);
   }
 
   @override
   ir.Primitive visitIsNot(ast.Send node,
                           ast.Node expression, DartType type, _) {
-    ir.Primitive receiver = visit(expression);
-    return irBuilder.buildTypeOperator(
-        receiver, type,
-        isTypeTest: true,
-        isNotCheck: true);
+    ir.Primitive value = visit(expression);
+    ir.Primitive check = irBuilder.buildTypeOperator(
+        value, type, isTypeTest: true);
+    return irBuilder.buildNegation(check);
   }
 
   ir.Primitive translateBinary(ast.Node left,
@@ -1000,10 +998,7 @@
   ir.Primitive visitUnary(ast.Send node,
                           op.UnaryOperator operator, ast.Node expression, _) {
     // TODO(johnniwinther): Clean up the creation of selectors.
-    Selector selector = new Selector(
-        SelectorKind.OPERATOR,
-        new PublicName(operator.selectorName),
-        CallStructure.NO_ARGS);
+    Selector selector = operator.selector;
     ir.Primitive receiver = translateReceiver(expression);
     return irBuilder.buildDynamicInvocation(receiver, selector, const []);
   }
@@ -1088,13 +1083,19 @@
   }
 
   @override
+  ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) {
+    return buildStaticFieldGet(field, sourceInformationBuilder.buildGet(node));
+  }
+
+  @override
   ir.Primitive handleStaticFieldInvoke(
       ast.Send node,
       FieldElement field,
       ast.NodeList arguments,
       CallStructure callStructure,
       _) {
-    ir.Primitive target = irBuilder.buildStaticFieldGet(field);
+    SourceInformation src = sourceInformationBuilder.buildGet(node);
+    ir.Primitive target = buildStaticFieldGet(field, src);
     return irBuilder.buildCallInvocation(target,
         callStructure,
         translateDynamicArguments(arguments, callStructure));
@@ -1245,123 +1246,26 @@
     return irBuilder.buildSuperIndexSet(function, visit(index), visit(rhs));
   }
 
-  @override
-  ir.Primitive visitCompoundIndexSet(
-      ast.SendSet node,
-      ast.Node receiver,
-      ast.Node index,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    ir.Primitive target = visit(receiver);
-    ir.Primitive indexValue = visit(index);
-    return translateCompound(
-        getValue: () {
-          Selector selector = new Selector.index();
-          List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
-          arguments =
-              normalizeDynamicArguments(selector.callStructure, arguments);
-          return irBuilder.buildDynamicInvocation(target, selector, arguments);
-        },
-        operator: operator,
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildDynamicIndexSet(target, indexValue, result);
-        });
-  }
-
-  @override
-  ir.Primitive visitSuperCompoundIndexSet(
-      ast.SendSet node,
-      FunctionElement getter,
-      FunctionElement setter,
-      ast.Node index,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    ir.Primitive indexValue = visit(index);
-    return translateCompound(
-        getValue: () {
-          return irBuilder.buildSuperIndex(getter, indexValue);
-        },
-        operator: operator,
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildSuperIndexSet(setter, indexValue, result);
-        });
-  }
-
-  ir.Primitive translatePrefixPostfix(
+  ir.Primitive translateCompounds(
       {ir.Primitive getValue(),
-       op.IncDecOperator operator,
-       void setValue(ir.Primitive value),
-       bool isPrefix}) {
-    ir.Primitive value = getValue();
-    Selector operatorSelector =
-        new Selector.binaryOperator(operator.selectorName);
-    List<ir.Primitive> arguments =
-        <ir.Primitive>[irBuilder.buildIntegerConstant(1)];
-    arguments = normalizeDynamicArguments(
-        operatorSelector.callStructure, arguments);
-    ir.Primitive result =
-        irBuilder.buildDynamicInvocation(value, operatorSelector, arguments);
-    setValue(result);
-    return isPrefix ? result : value;
-  }
-
-  ir.Primitive translateCompound(
-      {ir.Primitive getValue(),
-       op.AssignmentOperator operator,
-       ast.Node rhs,
+       CompoundRhs rhs,
        void setValue(ir.Primitive value)}) {
     ir.Primitive value = getValue();
     Selector operatorSelector =
-        new Selector.binaryOperator(operator.selectorName);
-    List<ir.Primitive> arguments = <ir.Primitive>[visit(rhs)];
+        new Selector.binaryOperator(rhs.operator.selectorName);
+    ir.Primitive rhsValue;
+    if (rhs.kind == CompoundKind.ASSIGNMENT) {
+      rhsValue = visit(rhs.rhs);
+    } else {
+      rhsValue = irBuilder.buildIntegerConstant(1);
+    }
+    List<ir.Primitive> arguments = <ir.Primitive>[rhsValue];
     arguments = normalizeDynamicArguments(
         operatorSelector.callStructure, arguments);
     ir.Primitive result =
         irBuilder.buildDynamicInvocation(value, operatorSelector, arguments);
     setValue(result);
-    return result;
-  }
-
-  @override
-  ir.Primitive handleDynamicCompound(
-      ast.Send node,
-      ast.Node receiver,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      Selector getterSelector,
-      Selector setterSelector,
-      _) {
-    ir.Primitive target = translateReceiver(receiver);
-    return translateCompound(
-        getValue: () => irBuilder.buildDynamicGet(target, getterSelector),
-        operator: operator,
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildDynamicSet(target, setterSelector, result);
-        });
-  }
-
-  @override
-  ir.Primitive handleDynamicPostfixPrefix(
-      ast.Send node,
-      ast.Node receiver,
-      op.IncDecOperator operator,
-      Selector getterSelector,
-      Selector setterSelector,
-      arg,
-      {bool isPrefix}) {
-    ir.Primitive target = translateReceiver(receiver);
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildDynamicGet(target, getterSelector),
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildDynamicSet(target, setterSelector, result);
-        },
-        isPrefix: isPrefix);
+    return rhs.kind == CompoundKind.POSTFIX ? value : result;
   }
 
   @override
@@ -1378,38 +1282,6 @@
   }
 
   @override
-  ir.Primitive handleLocalCompound(
-      ast.Send node,
-      LocalElement element,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildLocalVariableGet(element),
-        operator: operator,
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildLocalVariableSet(element, result);
-        });
-  }
-
-  @override
-  ir.Primitive handleLocalPostfixPrefix(
-      ast.Send node,
-      LocalElement element,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildLocalVariableGet(element),
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildLocalVariableSet(element, result);
-        },
-        isPrefix: isPrefix);
-  }
-
-  @override
   ir.Primitive handleLocalSet(
       ast.SendSet node,
       LocalElement element,
@@ -1419,38 +1291,6 @@
   }
 
   @override
-  ir.Primitive handleStaticFieldCompound(
-      ast.Send node,
-      FieldElement field,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildStaticFieldGet(field),
-        operator: operator,
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildStaticFieldSet(field, result);
-        });
-  }
-
-  @override
-  ir.Primitive handleStaticFieldPostfixPrefix(
-      ast.Send node,
-      FieldElement field,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildStaticFieldGet(field),
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildStaticFieldSet(field, result);
-        },
-        isPrefix: isPrefix);
-  }
-
-  @override
   ir.Primitive handleStaticFieldSet(
       ast.SendSet node,
       FieldElement field,
@@ -1478,243 +1318,6 @@
   }
 
   @override
-  ir.Primitive handleStaticGetterSetterCompound(
-      ast.Send node,
-      FunctionElement getter,
-      FunctionElement setter,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildStaticGetterGet(getter),
-        operator: operator,
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildStaticSetterSet(setter, result);
-        });
-  }
-
-  @override
-  ir.Primitive handleSuperFieldFieldPostfixPrefix(
-      ast.Send node,
-      FieldElement readField,
-      FieldElement writtenField,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildSuperFieldGet(readField),
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildSuperFieldSet(writtenField, result);
-        },
-        isPrefix: isPrefix);
-  }
-
-  @override
-  ir.Primitive handleSuperFieldSetterPostfixPrefix(
-      ast.Send node,
-      FieldElement field,
-      FunctionElement setter,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildSuperFieldGet(field),
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildSuperSetterSet(setter, result);
-        },
-        isPrefix: isPrefix);
-  }
-
-  @override
-  ir.Primitive handleSuperGetterFieldPostfixPrefix(
-      ast.Send node,
-      FunctionElement getter,
-      FieldElement field,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildSuperGetterGet(getter),
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildSuperFieldSet(field, result);
-        },
-        isPrefix: isPrefix);
-  }
-
-  @override
-  ir.Primitive handleSuperGetterSetterPostfixPrefix(
-      ast.Send node,
-      FunctionElement getter,
-      FunctionElement setter,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildSuperGetterGet(getter),
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildSuperSetterSet(setter, result);
-        },
-        isPrefix: isPrefix);
-  }
-
-  @override
-  ir.Primitive handleSuperMethodSetterPostfixPrefix(
-      ast.Send node,
-      FunctionElement method,
-      FunctionElement setter,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildSuperMethodGet(method),
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildSuperSetterSet(setter, result);
-        },
-        isPrefix: isPrefix);
-  }
-
-  @override
-  ir.Primitive handleStaticGetterSetterPostfixPrefix(
-      ast.Send node,
-      FunctionElement getter,
-      FunctionElement setter,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildStaticGetterGet(getter),
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildStaticSetterSet(setter, result);
-        },
-        isPrefix: isPrefix);
-  }
-
-  @override
-  ir.Primitive handleStaticMethodSetterCompound(
-      ast.Send node,
-      FunctionElement method,
-      FunctionElement setter,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildStaticFunctionGet(method),
-        operator: operator,
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildStaticSetterSet(setter, result);
-        });
-  }
-
-  @override
-  ir.Primitive handleStaticMethodSetterPostfixPrefix(
-      ast.Send node,
-      FunctionElement getter,
-      FunctionElement setter,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildStaticFunctionGet(getter),
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildStaticSetterSet(setter, result);
-        },
-        isPrefix: isPrefix);
-  }
-
-  @override
-  ir.Primitive handleDynamicIndexPostfixPrefix(
-      ast.Send node,
-      ast.Node receiver,
-      ast.Node index,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    ir.Primitive target = visit(receiver);
-    ir.Primitive indexValue = visit(index);
-    return translatePrefixPostfix(
-        getValue: () {
-          Selector selector = new Selector.index();
-          List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
-          arguments =
-              normalizeDynamicArguments(selector.callStructure, arguments);
-          return irBuilder.buildDynamicInvocation(target, selector, arguments);
-        },
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          Selector selector = new Selector.indexSet();
-          List<ir.Primitive> arguments = <ir.Primitive>[indexValue, result];
-          arguments =
-              normalizeDynamicArguments(selector.callStructure, arguments);
-          irBuilder.buildDynamicInvocation(target, selector, arguments);
-        },
-        isPrefix: isPrefix);
-  }
-
-  @override
-  ir.Primitive handleSuperIndexPostfixPrefix(
-      ast.Send node,
-      FunctionElement indexFunction,
-      FunctionElement indexSetFunction,
-      ast.Node index,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    ir.Primitive indexValue = visit(index);
-    return translatePrefixPostfix(
-        getValue: () {
-          return irBuilder.buildSuperIndex(indexFunction, indexValue);
-        },
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result);
-        },
-        isPrefix: isPrefix);
-  }
-
-  @override
-  ir.Primitive handleUnresolvedSuperGetterIndexPostfixPrefix(
-      ast.Send node,
-      Element element,
-      ast.Node index,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    return giveup(node, 'handleSuperUnresolvedGetterIndexPostfixPrefix');
-  }
-
-  @override
-  ir.Primitive handleUnresolvedSuperSetterIndexPostfixPrefix(
-      ast.Send node,
-      FunctionElement indexFunction,
-      Element element,
-      ast.Node index,
-      op.IncDecOperator operator,
-      arg,
-      {bool isPrefix}) {
-    return giveup(node, 'handleSuperUnresolvedGetterIndexPostfixPrefix');
-  }
-
-  @override
-  ir.Primitive visitUnresolvedSuperGetterCompoundIndexSet(
-      ast.Send node,
-      Element element,
-      ast.Node index,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      arg) {
-    return giveup(node, 'visitUnresolvedSuperGetterCompoundIndexSet');
-  }
-
-  @override
   ir.Primitive visitUnresolvedSuperIndexSet(
       ast.Send node,
       Element element,
@@ -1725,18 +1328,6 @@
   }
 
   @override
-  ir.Primitive visitUnresolvedSuperSetterCompoundIndexSet(
-      ast.Send node,
-      MethodElement getter,
-      Element element,
-      ast.Node index,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      arg) {
-    return giveup(node, 'visitUnresolvedSuperSetterCompoundIndexSet');
-  }
-
-  @override
   ir.Primitive handleStaticSetterSet(
       ast.SendSet node,
       FunctionElement setter,
@@ -1746,118 +1337,225 @@
   }
 
   @override
-  ir.Primitive visitSuperFieldCompound(
-      ast.Send node,
-      FieldElement field,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildSuperFieldGet(field),
-        operator: operator,
+  ir.Primitive handleTypeLiteralConstantCompounds(
+      ast.SendSet node,
+      ConstantExpression constant,
+      CompoundRhs rhs,
+      arg) {
+    return translateCompounds(
+        getValue: () => irBuilder.buildConstant(constant),
         rhs: rhs,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildSuperFieldSet(field, result);
-        });
+        setValue: (value) {}); // The binary operator will throw before this.
   }
 
   @override
-  ir.Primitive visitSuperFieldFieldPostfix(
+  ir.Primitive handleDynamicCompounds(
       ast.Send node,
-      FieldElement readField,
-      FieldElement writtenField,
-      op.IncDecOperator operator,
-      _) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildSuperFieldGet(readField),
-        operator: operator,
+      ast.Node receiver,
+      CompoundRhs rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      arg) {
+    ir.Primitive target = translateReceiver(receiver);
+    return translateCompounds(
+        getValue: () => irBuilder.buildDynamicGet(target, getterSelector),
+        rhs: rhs,
         setValue: (ir.Primitive result) {
-          irBuilder.buildSuperFieldSet(writtenField, result);
+          irBuilder.buildDynamicSet(target, setterSelector, result);
+        });
+  }
+
+  ir.Primitive buildLocalNoSuchSetter(Local local, ir.Primitive value) {
+    Selector selector = new Selector.setter(local.name, null);
+    return buildStaticNoSuchMethod(selector, [value]);
+  }
+
+  @override
+  ir.Primitive handleLocalCompounds(
+      ast.SendSet node,
+      LocalElement local,
+      CompoundRhs rhs,
+      arg,
+      {bool isSetterValid}) {
+    return translateCompounds(
+        getValue: () {
+          if (local.isFunction) {
+            return irBuilder.buildLocalFunctionGet(local);
+          } else {
+            return irBuilder.buildLocalVariableGet(local);
+          }
         },
-        isPrefix: false);
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          if (isSetterValid) {
+            irBuilder.buildLocalVariableSet(local, result);
+          } else {
+            return buildLocalNoSuchSetter(local, result);
+          }
+        });
+  }
+
+  ir.Primitive buildStaticNoSuchGetter(Element element) {
+    return buildStaticNoSuchMethod(
+        new Selector.getter(element.name, element.library),
+        const <ir.Primitive>[]);
+  }
+
+  ir.Primitive buildStaticNoSuchSetter(Element element, ir.Primitive value) {
+    return buildStaticNoSuchMethod(
+        new Selector.setter(element.name, element.library),
+        <ir.Primitive>[value]);
   }
 
   @override
-  ir.Primitive visitSuperFieldFieldPrefix(
-      ast.Send node,
-      FieldElement readField,
-      FieldElement writtenField,
-      op.IncDecOperator operator,
-      _) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildSuperFieldGet(readField),
-        operator: operator,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildSuperFieldSet(writtenField, result);
+  ir.Primitive handleStaticCompounds(
+      ast.SendSet node,
+      Element getter,
+      CompoundGetter getterKind,
+      Element setter,
+      CompoundSetter setterKind,
+      CompoundRhs rhs,
+      arg) {
+    return translateCompounds(
+        getValue: () {
+          switch (getterKind) {
+            case CompoundGetter.FIELD:
+              SourceInformation src = sourceInformationBuilder.buildGet(node);
+              return irBuilder.buildStaticFieldGet(getter, src);
+            case CompoundGetter.GETTER:
+              return irBuilder.buildStaticGetterGet(getter);
+            case CompoundGetter.METHOD:
+              return irBuilder.buildStaticFunctionGet(getter);
+            case CompoundGetter.UNRESOLVED:
+              return buildStaticNoSuchGetter(getter);
+          }
         },
-        isPrefix: true);
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          switch (setterKind) {
+            case CompoundSetter.FIELD:
+              return irBuilder.buildStaticFieldSet(setter, result);
+            case CompoundSetter.SETTER:
+              return irBuilder.buildStaticSetterSet(setter, result);
+            case CompoundSetter.INVALID:
+              // TODO(johnniwinther): Ensure [setter] is non null.
+              return buildStaticNoSuchSetter(
+                  setter != null ? setter : getter, result);
+          }
+        });
+  }
+
+  ir.Primitive buildSuperNoSuchGetter(Element element) {
+    return buildInstanceNoSuchMethod(
+        new Selector.getter(element.name, element.library),
+        const <ir.Primitive>[]);
+  }
+
+  ir.Primitive buildSuperNoSuchSetter(Element element, ir.Primitive value) {
+    return buildInstanceNoSuchMethod(
+        new Selector.setter(element.name, element.library),
+        <ir.Primitive>[value]);
   }
 
   @override
-  ir.Primitive visitSuperFieldSetterCompound(
-      ast.Send node,
-      FieldElement field,
-      FunctionElement setter,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildSuperFieldGet(field),
-        operator: operator,
+  ir.Primitive handleSuperCompounds(
+      ast.SendSet node,
+      Element getter,
+      CompoundGetter getterKind,
+      Element setter,
+      CompoundSetter setterKind,
+      CompoundRhs rhs,
+      arg) {
+    return translateCompounds(
+        getValue: () {
+          switch (getterKind) {
+            case CompoundGetter.FIELD:
+              return irBuilder.buildSuperFieldGet(getter);
+            case CompoundGetter.GETTER:
+              return irBuilder.buildSuperGetterGet(getter);
+            case CompoundGetter.METHOD:
+              return irBuilder.buildSuperMethodGet(getter);
+            case CompoundGetter.UNRESOLVED:
+              // TODO(johnniwinther): Ensure [getter] is not null.
+              return buildSuperNoSuchGetter(getter != null ? getter : setter);
+          }
+        },
         rhs: rhs,
         setValue: (ir.Primitive result) {
-          irBuilder.buildSuperSetterSet(setter, result);
+          switch (setterKind) {
+            case CompoundSetter.FIELD:
+              return irBuilder.buildSuperFieldSet(setter, result);
+            case CompoundSetter.SETTER:
+              return irBuilder.buildSuperSetterSet(setter, result);
+            case CompoundSetter.INVALID:
+              return buildSuperNoSuchSetter(setter, result);
+          }
         });
   }
 
   @override
-  ir.Primitive visitSuperGetterFieldCompound(
-      ast.Send node,
-      FunctionElement getter,
-      FieldElement field,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildSuperGetterGet(getter),
-        operator: operator,
+  ir.Primitive handleTypeVariableTypeLiteralCompounds(
+      ast.SendSet node,
+      TypeVariableElement typeVariable,
+      CompoundRhs rhs,
+      arg) {
+    return translateCompounds(
+        getValue: () => irBuilder.buildReifyTypeVariable(typeVariable.type),
+        rhs: rhs,
+        setValue: (value) {}); // The binary operator will throw before this.
+  }
+
+  @override
+  ir.Primitive handleIndexCompounds(
+      ast.SendSet node,
+      ast.Node receiver,
+      ast.Node index,
+      CompoundRhs rhs,
+      arg) {
+    ir.Primitive target = visit(receiver);
+    ir.Primitive indexValue = visit(index);
+    return translateCompounds(
+        getValue: () {
+          Selector selector = new Selector.index();
+          List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
+          arguments =
+              normalizeDynamicArguments(selector.callStructure, arguments);
+          return irBuilder.buildDynamicInvocation(target, selector, arguments);
+        },
         rhs: rhs,
         setValue: (ir.Primitive result) {
-          irBuilder.buildSuperFieldSet(field, result);
+          irBuilder.buildDynamicIndexSet(target, indexValue, result);
         });
   }
 
   @override
-  ir.Primitive visitSuperGetterSetterCompound(
-      ast.Send node,
-      FunctionElement getter,
-      FunctionElement setter,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildSuperGetterGet(getter),
-        operator: operator,
+  ir.Primitive handleSuperIndexCompounds(
+      ast.SendSet node,
+      Element indexFunction,
+      Element indexSetFunction,
+      ast.Node index,
+      CompoundRhs rhs,
+      arg,
+      {bool isGetterValid,
+       bool isSetterValid}) {
+    ir.Primitive indexValue = visit(index);
+    return translateCompounds(
+        getValue: () {
+          if (isGetterValid) {
+            return irBuilder.buildSuperIndex(indexFunction, indexValue);
+          } else {
+            return buildInstanceNoSuchMethod(
+                new Selector.index(), <ir.Primitive>[indexValue]);
+          }
+        },
         rhs: rhs,
         setValue: (ir.Primitive result) {
-          irBuilder.buildSuperSetterSet(setter, result);
-        });
-  }
-
-  @override
-  ir.Primitive visitSuperMethodSetterCompound(
-      ast.Send node,
-      FunctionElement method,
-      FunctionElement setter,
-      op.AssignmentOperator operator,
-      ast.Node rhs,
-      _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildSuperMethodGet(method),
-        operator: operator,
-        rhs: rhs,
-        setValue: (ir.Primitive result) {
-          irBuilder.buildSuperSetterSet(setter, result);
+          if (isSetterValid) {
+            irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result);
+          } else {
+            buildInstanceNoSuchMethod(
+                new Selector.indexSet(), <ir.Primitive>[indexValue, result]);
+          }
         });
   }
 
@@ -1917,7 +1615,7 @@
   }
 
   @override
-  ir.Primitive errorUnresolvedCompound(
+  ir.Primitive visitUnresolvedCompound(
       ast.Send node,
       Element element,
       op.AssignmentOperator operator,
@@ -1954,7 +1652,7 @@
   ir.Primitive errorNonConstantConstructorInvoke(
       ast.NewExpression node,
       Element element,
-      InterfaceType type,
+      DartType type,
       ast.NodeList arguments,
       CallStructure callStructure, _) {
     assert(compiler.compilationFailed);
@@ -1979,24 +1677,6 @@
   }
 
   @override
-  ir.Primitive errorUnresolvedPostfix(
-      ast.Send node,
-      Element element,
-      op.IncDecOperator operator, _) {
-    // TODO(asgerf): Which ones are missing? The getter and/or the setter?
-    return buildStaticNoSuchMethod(elements.getSelector(node), []);
-  }
-
-  @override
-  ir.Primitive errorUnresolvedPrefix(
-      ast.Send node,
-      Element element,
-      op.IncDecOperator operator, _) {
-    // TODO(asgerf): Which ones are missing? The getter and/or the setter?
-    return buildStaticNoSuchMethod(elements.getSelector(node), []);
-  }
-
-  @override
   ir.Primitive visitUnresolvedRedirectingFactoryConstructorInvoke(
        ast.NewExpression node,
        ConstructorElement constructor,
@@ -2011,7 +1691,7 @@
   }
 
   @override
-  ir.Primitive errorUnresolvedSet(
+  ir.Primitive visitUnresolvedSet(
       ast.Send node,
       Element element,
       ast.Node rhs, _) {
@@ -2019,18 +1699,6 @@
   }
 
   @override
-  ir.Primitive errorUnresolvedSuperCompoundIndexSet(
-      ast.SendSet node,
-      Element element,
-      ast.Node index,
-      op.AssignmentOperator operator,
-      ast.Node rhs, _) {
-    // Assume the index getter is missing.
-    Selector selector = useSelectorTypeOfNode(new Selector.index(), node);
-    return buildInstanceNoSuchMethod(selector, [visit(index)]);
-  }
-
-  @override
   ir.Primitive visitUnresolvedSuperIndex(
       ast.Send node,
       Element function,
@@ -2041,40 +1709,6 @@
   }
 
   @override
-  ir.Primitive errorUnresolvedSuperIndexPostfix(
-      ast.Send node,
-      Element function,
-      ast.Node index,
-      op.IncDecOperator operator, _) {
-    // Assume the index getter is missing.
-    Selector selector = useSelectorTypeOfNode(new Selector.index(), node);
-    return buildInstanceNoSuchMethod(selector, [visit(index)]);
-  }
-
-  @override
-  ir.Primitive errorUnresolvedSuperIndexPrefix(
-      ast.Send node,
-      Element function,
-      ast.Node index,
-      op.IncDecOperator operator, _) {
-    // Assume the index getter is missing.
-    Selector selector = useSelectorTypeOfNode(new Selector.index(), node);
-    return buildInstanceNoSuchMethod(selector, [visit(index)]);
-  }
-
-  @override
-  ir.Primitive errorUnresolvedSuperIndexSet(
-      ast.SendSet node,
-      Element element,
-      ast.Node index,
-      ast.Node rhs, _) {
-    Selector selector = useSelectorTypeOfNode(new Selector.index(), node);
-    return buildInstanceNoSuchMethod(
-        selector,
-        [visit(index), visit(rhs)]);
-  }
-
-  @override
   ir.Primitive visitUnresolvedSuperBinary(
       ast.Send node,
       Element element,
@@ -2113,45 +1747,7 @@
   }
 
   @override
-  ir.Primitive errorTopLevelFunctionSet(
-      ast.Send node,
-      MethodElement function,
-      ast.Node rhs, _) {
-    return buildStaticNoSuchMethod(
-        new Selector.setter(function.name, function.library),
-        [visit(rhs)]);
-  }
-
-  @override
-  ir.Primitive errorTopLevelSetterGet(
-      ast.Send node,
-      FunctionElement setter, _) {
-    return buildStaticNoSuchMethod(
-        new Selector.getter(setter.name, setter.library), []);
-  }
-
-  @override
-  ir.Primitive errorTopLevelGetterSet(
-      ast.SendSet node,
-      FunctionElement getter,
-      ast.Node rhs, _) {
-    return buildStaticNoSuchMethod(
-        new Selector.setter(getter.name, getter.library),
-        [visit(rhs)]);
-  }
-
-  @override
-  ir.Primitive errorTopLevelSetterInvoke(
-      ast.Send node,
-      FunctionElement setter,
-      ast.NodeList arguments,
-      CallStructure callStructure, _) {
-    return buildStaticNoSuchMethod(
-        new Selector.getter(setter.name, setter.library), []);
-  }
-
-  @override
-  ir.Primitive errorClassTypeLiteralSet(
+  ir.Primitive visitClassTypeLiteralSet(
       ast.SendSet node,
       TypeConstantExpression constant,
       ast.Node rhs, _) {
@@ -2162,7 +1758,7 @@
   }
 
   @override
-  ir.Primitive errorTypedefTypeLiteralSet(
+  ir.Primitive visitTypedefTypeLiteralSet(
       ast.SendSet node,
       TypeConstantExpression constant,
       ast.Node rhs, _) {
@@ -2173,7 +1769,7 @@
   }
 
   @override
-  ir.Primitive errorTypeVariableTypeLiteralSet(
+  ir.Primitive visitTypeVariableTypeLiteralSet(
       ast.SendSet node,
       TypeVariableElement element,
       ast.Node rhs, _) {
@@ -2182,7 +1778,7 @@
   }
 
   @override
-  ir.Primitive errorDynamicTypeLiteralSet(
+  ir.Primitive visitDynamicTypeLiteralSet(
       ast.SendSet node,
       ConstantExpression constant,
       ast.Node rhs, _) {
@@ -2201,168 +1797,18 @@
   }
 
   @override
-  ir.Primitive errorClassTypeLiteralCompound(
-      ast.Send node,
-      ConstantExpression constant,
-      op.AssignmentOperator operator,
-      ast.Node rhs, _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildConstant(constant),
-        operator: operator,
-        rhs: rhs,
-        setValue: (value) {}); // The binary operator will throw before this.
-  }
-
-  @override
-  ir.Primitive errorClassTypeLiteralPostfix(
-      ast.Send node,
-      ConstantExpression constant,
-      op.IncDecOperator operator, _) {
-    return translatePrefixPostfix(
-      getValue: () => irBuilder.buildConstant(constant),
-      operator: operator,
-      setValue: (value) {}, // The binary operator will throw before this.
-      isPrefix: false);
-  }
-
-  @override
-  ir.Primitive errorClassTypeLiteralPrefix(
-      ast.Send node,
-      ConstantExpression constant,
-      op.IncDecOperator operator, _) {
-    return translatePrefixPostfix(
-      getValue: () => irBuilder.buildConstant(constant),
-      operator: operator,
-      setValue: (value) {}, // The binary operator will throw before this.
-      isPrefix: true);
-  }
-
-  @override
-  ir.Primitive errorDynamicTypeLiteralCompound(
-      ast.Send node,
-      ConstantExpression constant,
-      op.AssignmentOperator operator,
-      ast.Node rhs, _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildConstant(constant),
-        operator: operator,
-        rhs: rhs,
-        setValue: (value) {}); // The binary operator will throw before this.
-  }
-
-  @override
-  ir.Primitive errorDynamicTypeLiteralPostfix(
-      ast.Send node,
-      ConstantExpression constant,
-      op.IncDecOperator operator, _) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildConstant(constant),
-        operator: operator,
-        setValue: (value) {}, // The binary operator will throw before this.
-        isPrefix: false);
-  }
-
-  @override
-  ir.Primitive errorDynamicTypeLiteralPrefix(
-      ast.Send node,
-      ConstantExpression constant,
-      op.IncDecOperator operator, _) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildConstant(constant),
-        operator: operator,
-        setValue: (value) {}, // The binary operator will throw before this.
-        isPrefix: true);
-  }
-
-  @override
-  ir.Primitive errorFinalLocalVariableCompound(
-      ast.Send node,
-      LocalVariableElement variable,
-      op.AssignmentOperator operator,
-      ast.Node rhs, _) {
-    Selector selector = new Selector.setter(variable.name, null);
-    return translateCompound(
-        getValue: () => irBuilder.buildLocalVariableGet(variable),
-        operator: operator,
-        rhs: rhs,
-        setValue: (value) => buildStaticNoSuchMethod(selector, [value]));
-  }
-
-  @override
-  ir.Primitive errorFinalLocalVariableSet(
-      ast.SendSet node,
-      LocalVariableElement variable,
-      ast.Node rhs, _) {
-    Selector selector = new Selector.setter(variable.name, null);
-    return buildStaticNoSuchMethod(selector, [visit(rhs)]);
-  }
-
-  @override
-  ir.Primitive errorFinalParameterCompound(
-      ast.Send node,
-      ParameterElement parameter,
-      op.AssignmentOperator operator,
-      ast.Node rhs, _) {
-    Selector selector = new Selector.setter(parameter.name, null);
-    return translateCompound(
-        getValue: () => irBuilder.buildLocalVariableGet(parameter),
-        operator: operator,
-        rhs: rhs,
-        setValue: (value) => buildStaticNoSuchMethod(selector, [value]));
-  }
-
-  @override
-  ir.Primitive errorFinalParameterSet(
-      ast.SendSet node,
-      ParameterElement parameter,
-      ast.Node rhs, _) {
-    Selector selector = new Selector.setter(parameter.name, null);
-    return buildStaticNoSuchMethod(selector, [visit(rhs)]);
-  }
-
-  @override
-  ir.Primitive errorFinalStaticFieldCompound(
-      ast.Send node,
-      FieldElement field,
-      op.AssignmentOperator operator,
-      ast.Node rhs, _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildStaticFieldGet(field),
-        operator: operator,
-        rhs: rhs,
-        setValue: (value) => buildStaticNoSuchMethod(
-            new Selector.setter(field.name, field.library), [value]));
-  }
-
-  @override
-  ir.Primitive errorFinalStaticFieldSet(
+  ir.Primitive handleFinalStaticFieldSet(
       ast.SendSet node,
       FieldElement field,
       ast.Node rhs, _) {
-    // TODO(asgerf): Include class name somehow?
+    // TODO(asgerf): Include class name somehow for static class members?
     return buildStaticNoSuchMethod(
         new Selector.setter(field.name, field.library),
         [visit(rhs)]);
   }
 
   @override
-  ir.Primitive errorFinalSuperFieldCompound(
-      ast.Send node,
-      FieldElement field,
-      op.AssignmentOperator operator,
-      ast.Node rhs, _) {
-    Selector selector = useSelectorTypeOfNode(
-        new Selector.setter(field.name, field.library),
-        node);
-    return translateCompound(
-        getValue: () => irBuilder.buildSuperFieldGet(field),
-        operator: operator,
-        rhs: rhs,
-        setValue: (value) => buildInstanceNoSuchMethod(selector, [value]));
-  }
-
-  @override
-  ir.Primitive errorFinalSuperFieldSet(
+  ir.Primitive visitFinalSuperFieldSet(
       ast.SendSet node,
       FieldElement field,
       ast.Node rhs, _) {
@@ -2373,80 +1819,17 @@
   }
 
   @override
-  ir.Primitive errorFinalTopLevelFieldCompound(
-      ast.Send node,
-      FieldElement field,
-      op.AssignmentOperator operator,
-      ast.Node rhs, _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildStaticFieldGet(field),
-        operator: operator,
-        rhs: rhs,
-        setValue: (value) => buildStaticNoSuchMethod(
-            new Selector.setter(field.name, field.library), [value]));
-  }
-
-  @override
-  ir.Primitive errorFinalTopLevelFieldSet(
+  ir.Primitive handleImmutableLocalSet(
       ast.SendSet node,
-      FieldElement field,
+      LocalElement local,
       ast.Node rhs, _) {
     return buildStaticNoSuchMethod(
-        new Selector.setter(field.name, field.library),
+        new Selector.setter(local.name, null),
         [visit(rhs)]);
   }
 
   @override
-  ir.Primitive errorLocalFunctionCompound(
-      ast.Send node,
-      LocalFunctionElement function,
-      op.AssignmentOperator operator,
-      ast.Node rhs, _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildLocalFunctionGet(function),
-        operator: operator,
-        rhs: rhs,
-        setValue: (value) {}); // Binary operator will throw before this.
-  }
-
-  @override
-  ir.Primitive errorLocalFunctionPostfix(
-      ast.Send node,
-      LocalFunctionElement function,
-      op.IncDecOperator operator,
-      _) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildLocalFunctionGet(function),
-        operator: operator,
-        setValue: (value) {}, // Binary operator will throw before this.
-        isPrefix: false);
-  }
-
-  @override
-  ir.Primitive errorLocalFunctionPrefix(
-      ast.Send node,
-      LocalFunctionElement function,
-      op.IncDecOperator operator,
-      _) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildLocalFunctionGet(function),
-        operator: operator,
-        setValue: (value) {}, // Binary operator will throw before this.
-        isPrefix: true);
-  }
-
-  @override
-  ir.Primitive errorLocalFunctionSet(
-      ast.SendSet node,
-      LocalFunctionElement function,
-      ast.Node rhs, _) {
-    return buildStaticNoSuchMethod(
-        new Selector.setter(function.name, null),
-        [visit(rhs)]);
-  }
-
-  @override
-  ir.Primitive errorStaticFunctionSet(
+  ir.Primitive handleStaticFunctionSet(
       ast.Send node,
       MethodElement function,
       ast.Node rhs,
@@ -2457,7 +1840,7 @@
   }
 
   @override
-  ir.Primitive errorStaticGetterSet(
+  ir.Primitive handleStaticGetterSet(
       ast.SendSet node,
       FunctionElement getter,
       ast.Node rhs,
@@ -2468,7 +1851,7 @@
   }
 
   @override
-  ir.Primitive errorStaticSetterGet(
+  ir.Primitive handleStaticSetterGet(
       ast.Send node,
       FunctionElement setter,
       _) {
@@ -2478,7 +1861,7 @@
   }
 
   @override
-  ir.Primitive errorStaticSetterInvoke(
+  ir.Primitive handleStaticSetterInvoke(
       ast.Send node,
       FunctionElement setter,
       ast.NodeList arguments,
@@ -2492,7 +1875,7 @@
   }
 
   @override
-  ir.Primitive errorSuperGetterSet(
+  ir.Primitive visitSuperGetterSet(
       ast.SendSet node,
       FunctionElement getter,
       ast.Node rhs,
@@ -2504,7 +1887,7 @@
   }
 
   @override
-  ir.Primitive errorSuperMethodSet(
+  ir.Primitive visitSuperMethodSet(
       ast.Send node,
       MethodElement method,
       ast.Node rhs,
@@ -2516,7 +1899,7 @@
   }
 
   @override
-  ir.Primitive errorSuperSetterGet(
+  ir.Primitive visitSuperSetterGet(
       ast.Send node,
       FunctionElement setter, _) {
     Selector selector = useSelectorTypeOfNode(
@@ -2526,7 +1909,7 @@
   }
 
   @override
-  ir.Primitive errorSuperSetterInvoke(
+  ir.Primitive visitSuperSetterInvoke(
       ast.Send node,
       FunctionElement setter,
       ast.NodeList arguments,
@@ -2540,80 +1923,6 @@
     return buildInstanceNoSuchMethod(selector, args);
   }
 
-  @override
-  ir.Primitive errorTypeVariableTypeLiteralCompound(
-      ast.Send node,
-      TypeVariableElement element,
-      op.AssignmentOperator operator,
-      ast.Node rhs, _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildReifyTypeVariable(element.type),
-        operator: operator,
-        rhs: rhs,
-        setValue: (value) {}); // The binary operator will throw before this.
-  }
-
-  @override
-  ir.Primitive errorTypeVariableTypeLiteralPostfix(
-      ast.Send node,
-      TypeVariableElement element,
-      op.IncDecOperator operator, _) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildReifyTypeVariable(element.type),
-        operator: operator,
-        setValue: (value) {}, // The binary operator will throw before this.
-        isPrefix: false);
-  }
-
-  @override
-  ir.Primitive errorTypeVariableTypeLiteralPrefix(
-      ast.Send node,
-      TypeVariableElement element,
-      op.IncDecOperator operator, _) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildReifyTypeVariable(element.type),
-        operator: operator,
-        setValue: (value) {}, // The binary operator will throw before this.
-        isPrefix: true);
-  }
-
-  @override
-  ir.Primitive errorTypedefTypeLiteralCompound(
-      ast.Send node,
-      ConstantExpression constant,
-      op.AssignmentOperator operator,
-      ast.Node rhs, _) {
-    return translateCompound(
-        getValue: () => irBuilder.buildConstant(constant),
-        operator: operator,
-        rhs: rhs,
-        setValue: (value) {}); // The binary operator will throw before this.
-  }
-
-  @override
-  ir.Primitive errorTypedefTypeLiteralPostfix(
-      ast.Send node,
-      ConstantExpression constant,
-      op.IncDecOperator operator, _) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildConstant(constant),
-        operator: operator,
-        setValue: (value) {}, // The binary operator will throw before this.
-        isPrefix: false);
-  }
-
-  @override
-  ir.Primitive errorTypedefTypeLiteralPrefix(
-      ast.Send node,
-      TypeConstantExpression constant,
-      op.IncDecOperator operator, _) {
-    return translatePrefixPostfix(
-        getValue: () => irBuilder.buildConstant(constant),
-        operator: operator,
-        setValue: (value) {}, // The binary operator will throw before this.
-        isPrefix: true);
-  }
-
   ir.RootNode nullIfGiveup(ir.RootNode action()) {
     try {
       return action();
@@ -2974,6 +2283,10 @@
   ir.Primitive buildAbstractClassInstantiationError(ClassElement element) {
     return giveup(null, 'Abstract class instantiation: ${element.name}');
   }
+
+  ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) {
+    return irBuilder.buildStaticFieldLazyGet(field, src);
+  }
 }
 
 /// The [IrBuilder]s view on the information about the program that has been
@@ -2989,6 +2302,8 @@
   bool requiresRuntimeTypesFor(ClassElement cls) {
     return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls);
   }
+
+  ClassElement get nullClass => _compiler.nullClass;
 }
 
 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder].
@@ -3013,6 +2328,7 @@
                      SourceInformationBuilder sourceInformationBuilder)
       : super(elements, compiler, sourceInformationBuilder);
 
+
   /// Builds the IR for creating an instance of the closure class corresponding
   /// to the given nested function.
   ClosureClassElement makeSubFunction(ast.FunctionExpression node) {
@@ -3112,6 +2428,17 @@
           root = buildFunction(element);
           break;
 
+        case ElementKind.FIELD:
+          if (Elements.isStaticOrTopLevel(element)) {
+            root = buildStaticFieldInitializer(element);
+          } else {
+            // Instance field initializers are inlined in the constructor,
+            // so we shouldn't need to build anything here.
+            // TODO(asgerf): But what should we return?
+            return null;
+          }
+          break;
+
         default:
           compiler.internalError(element, "Unexpected element type $element");
       }
@@ -3120,6 +2447,23 @@
     });
   }
 
+  ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) {
+    if (!backend.constants.lazyStatics.contains(element)) {
+      return null; // Nothing to do.
+    }
+    closureClassMap =
+        compiler.closureToClassMapper.computeClosureToClassMapping(
+            element,
+            element.node,
+            elements);
+    IrBuilder builder = getBuilderFor(element);
+    return withBuilder(builder, () {
+      ir.Primitive initialValue = visit(element.initializer);
+      irBuilder.buildReturn(initialValue);
+      return irBuilder.makeLazyFieldInitializer();
+    });
+  }
+
   /// Builds the IR for an [expression] taken from a different [context].
   ///
   /// Such expressions need to be compiled with a different [sourceFile] and
@@ -3158,6 +2502,8 @@
   /// 3. Calls constructor body and super constructor bodies.
   /// 4. Returns the created object.
   ir.FunctionDefinition buildConstructor(ConstructorElement constructor) {
+    // TODO(asgerf): Optimization: If constructor is redirecting, then just
+    //               evaluate arguments and call the target constructor.
     constructor = constructor.implementation;
     ClassElement classElement = constructor.enclosingClass.implementation;
 
@@ -3258,21 +2604,25 @@
   /// All constructors will be added to [supers], with superconstructors first.
   void evaluateConstructorFieldInitializers(ConstructorElement constructor,
                                             List<ConstructorElement> supers) {
-    // Evaluate declaration-site field initializers.
     ClassElement enclosingClass = constructor.enclosingClass.implementation;
-    enclosingClass.forEachInstanceField((ClassElement c, FieldElement field) {
-      if (field.initializer != null) {
-        fieldValues[field] = inlineExpression(field, field.initializer);
-      } else {
-        if (Elements.isNativeOrExtendsNative(c)) {
-          // Native field is initialized elsewhere.
+    // Evaluate declaration-site field initializers, unless this constructor
+    // redirects to another using a `this()` initializer. In that case, these
+    // will be initialized by the effective target constructor.
+    if (!constructor.isRedirectingGenerative) {
+      enclosingClass.forEachInstanceField((ClassElement c, FieldElement field) {
+        if (field.initializer != null) {
+          fieldValues[field] = inlineExpression(field, field.initializer);
         } else {
-          // Fields without an initializer default to null.
-          // This value will be overwritten below if an initializer is found.
-          fieldValues[field] = irBuilder.buildNullConstant();
+          if (Elements.isNativeOrExtendsNative(c)) {
+            // Native field is initialized elsewhere.
+          } else {
+            // Fields without an initializer default to null.
+            // This value will be overwritten below if an initializer is found.
+            fieldValues[field] = irBuilder.buildNullConstant();
+          }
         }
-      }
-    });
+      });
+    }
     // Evaluate initializing parameters, e.g. `Foo(this.x)`.
     constructor.functionSignature.orderedForEachParameter(
         (ParameterElement parameter) {
@@ -3296,7 +2646,11 @@
           // Super or this initializer.
           ConstructorElement target = elements[initializer].implementation;
           Selector selector = elements.getSelector(initializer);
-          List<ir.Primitive> arguments = initializer.arguments.mapToList(visit);
+          ir.Primitive evaluateArgument(ast.Node arg) {
+            return inlineExpression(constructor, arg);
+          }
+          List<ir.Primitive> arguments =
+              initializer.arguments.mapToList(evaluateArgument);
           loadArguments(target, selector, arguments);
           evaluateConstructorFieldInitializers(target, supers);
           hasConstructorCall = true;
@@ -3590,10 +2944,11 @@
       _) {
     List<ir.Primitive> arguments =
         node.send.arguments.mapToList(visit, growable:false);
-    arguments = normalizeStaticArguments(
-        callStructure, constructor, arguments);
+    // Use default values from the effective target, not the immediate target.
+    ConstructorElement target = constructor.effectiveTarget;
+    arguments = normalizeStaticArguments(callStructure, target, arguments);
     return irBuilder.buildConstructorInvocation(
-        constructor.effectiveTarget,
+        target,
         callStructure,
         constructor.computeEffectiveTargetType(type),
         arguments);
@@ -3637,6 +2992,24 @@
         new CallStructure.unnamed(1),
         [irBuilder.buildStringConstant(element.name)]);
   }
+
+  @override
+  ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) {
+    SourceInformation src = sourceInformationBuilder.buildGet(node);
+    return buildStaticFieldGet(field, src);
+  }
+
+  ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) {
+    ConstantExpression constant =
+        backend.constants.getConstantForVariable(field);
+    if (constant != null && !field.isAssignable) {
+      return irBuilder.buildConstant(constant);
+    } else if (backend.constants.lazyStatics.contains(field)) {
+      return irBuilder.buildStaticFieldLazyGet(field, src);
+    } else {
+      return irBuilder.buildStaticFieldGet(field, src);
+    }
+  }
 }
 
 /// Perform simple post-processing on the initial CPS-translated root term.
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index 000a852..32c50ef 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -41,6 +41,7 @@
   bool get hasMultipleUses  => !hasAtMostOneUse;
 
   void substituteFor(Definition<T> other) {
+    if (other == this) return;
     if (other.hasNoUses) return;
     Reference<T> previous, current = other.firstRef;
     do {
@@ -401,17 +402,22 @@
 // But then we need to special-case for is-checks with an erroneous .type as
 // these will throw.
 class TypeOperator extends Expression {
-  final Reference<Primitive> receiver;
+  Reference<Primitive> value;
   final DartType type;
+  /// Type arguments to [type]. Since [type] may reference type variables in the
+  /// enclosing class, these are not constant.
+  final List<Reference<Primitive>> typeArguments;
   final Reference<Continuation> continuation;
   // TODO(johnniwinther): Use `Operator` class to encapsule the operator type.
   final bool isTypeTest;
 
-  TypeOperator(Primitive receiver,
+  TypeOperator(Primitive value,
                this.type,
+               List<Primitive> typeArguments,
                Continuation cont,
                {bool this.isTypeTest})
-      : this.receiver = new Reference<Primitive>(receiver),
+      : this.value = new Reference<Primitive>(value),
+        this.typeArguments = _referenceList(typeArguments),
         this.continuation = new Reference<Continuation>(cont) {
     assert(isTypeTest != null);
   }
@@ -652,6 +658,25 @@
   accept(Visitor visitor) => visitor.visitSetStatic(this);
 }
 
+/// Reads the value of a lazily initialized static field.
+///
+/// If the field has not yet been initialized, its initializer is evaluated
+/// and assigned to the field.
+///
+/// [continuation] is then invoked with the value of the field as argument.
+class GetLazyStatic extends Expression {
+  final FieldElement element;
+  final Reference<Continuation> continuation;
+  final SourceInformation sourceInformation;
+
+  GetLazyStatic(this.element,
+                Continuation cont,
+                this.sourceInformation)
+      : continuation = new Reference<Continuation>(cont);
+
+  accept(Visitor visitor) => visitor.visitGetLazyStatic(this);
+}
+
 /// Creates an object for holding boxed variables captured by a closure.
 class CreateBox extends Primitive implements JsSpecificNode {
   accept(Visitor visitor) => visitor.visitCreateBox(this);
@@ -844,11 +869,9 @@
 
 /// Identifies a mutable variable.
 class MutableVariable extends Definition {
-  /// Body of source code that declares this mutable variable.
-  ExecutableElement host;
   Entity hint;
 
-  MutableVariable(this.host, this.hint);
+  MutableVariable(this.hint);
 
   accept(Visitor v) => v.visitMutableVariable(this);
 }
@@ -863,7 +886,7 @@
 /// A function definition, consisting of parameters and a body.  The parameters
 /// include a distinguished continuation parameter (held by the body).
 class FunctionDefinition extends RootNode {
-  final FunctionElement element;
+  final ExecutableElement element;
   final Parameter thisParameter;
   /// Mixed list of [Parameter]s and [MutableVariable]s.
   final List<Definition> parameters;
@@ -1034,6 +1057,7 @@
   T visitSetMutableVariable(SetMutableVariable node);
   T visitDeclareFunction(DeclareFunction node);
   T visitSetStatic(SetStatic node);
+  T visitGetLazyStatic(GetLazyStatic node);
 
   // Definitions.
   T visitLiteralList(LiteralList node);
@@ -1225,7 +1249,8 @@
   visitTypeOperator(TypeOperator node) {
     processTypeOperator(node);
     processReference(node.continuation);
-    processReference(node.receiver);
+    processReference(node.value);
+    node.typeArguments.forEach(processReference);
   }
 
   processSetMutableVariable(SetMutableVariable node) {}
@@ -1244,6 +1269,12 @@
     visit(node.body);
   }
 
+  processGetLazyStatic(GetLazyStatic node) {}
+  visitGetLazyStatic(GetLazyStatic node) {
+    processGetLazyStatic(node);
+    processReference(node.continuation);
+  }
+
   // Definitions.
 
   processLiteralList(LiteralList node) {}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
index 5cc52ce..2d5294b 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
@@ -290,10 +290,12 @@
   }
 
   String visitTypeOperator(TypeOperator node) {
-    String receiver = access(node.receiver);
+    String value = access(node.value);
     String cont = access(node.continuation);
     String operator = node.isTypeTest ? 'is' : 'as';
-    return '$indentation(TypeOperator $operator $receiver ${node.type} $cont)';
+    String typeArguments = node.typeArguments.map(access).join(' ');
+    return '$indentation(TypeOperator $operator $value ${node.type} '
+           '($typeArguments) $cont)';
   }
 
   String visitLiteralList(LiteralList node) {
@@ -347,6 +349,12 @@
     return '$indentation(SetStatic $element $value\n$body)';
   }
 
+  String visitGetLazyStatic(GetLazyStatic node) {
+    String element = node.element.name;
+    String cont = access(node.continuation);
+    return '$indentation(GetLazyStatic $element $cont)';
+  }
+
   String visitCreateBox(CreateBox node) {
     return '(CreateBox)';
   }
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
index 16e247f..77b757f 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
@@ -236,8 +236,9 @@
     String dummy = names.name(node);
     String operator = node.isTypeTest ? 'is' : 'as';
     List<String> entries = new List<String>();
-    String receiver = formatReference(node.receiver);
-    printStmt(dummy, "TypeOperator ($operator $receiver ${node.type})");
+    String value = formatReference(node.value);
+    String kont = formatReference(node.continuation);
+    printStmt(dummy, "TypeOperator ($operator $value ${node.type}) $kont");
   }
 
   visitInvokeContinuation(cps_ir.InvokeContinuation node) {
@@ -329,6 +330,12 @@
     visit(node.body);
   }
 
+  visitGetLazyStatic(cps_ir.GetLazyStatic node) {
+    String dummy = names.name(node);
+    String kont = formatReference(node.continuation);
+    printStmt(dummy, "GetLazyStatic $kont");
+  }
+
   visitCreateBox(cps_ir.CreateBox node) {
     return 'CreateBox';
   }
@@ -556,6 +563,10 @@
     visit(exp.body);
   }
 
+  visitGetLazyStatic(cps_ir.GetLazyStatic exp) {
+    addEdgeToContinuation(exp.continuation);
+  }
+
   visitDeclareFunction(cps_ir.DeclareFunction exp) {
     visit(exp.body);
   }
diff --git a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
index f834d33..5a9fe92 100644
--- a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
+++ b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
@@ -585,8 +585,9 @@
   }
 
   processTypeOperator(TypeOperator node) {
+    node.typeArguments.forEach((Reference ref) => ref.parent = node);
     node.continuation.parent = node;
-    node.receiver.parent = node;
+    node.value.parent = node;
   }
 
   processSetMutableVariable(SetMutableVariable node) {
@@ -605,6 +606,10 @@
     node.value.parent = node;
   }
 
+  processGetLazyStatic(GetLazyStatic node) {
+    node.continuation.parent = node;
+  }
+
   // Definitions.
 
   processLiteralList(LiteralList node) {
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index c0cdcb1..842d460 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -301,7 +301,8 @@
   void visitTypeOperator(TypeOperator node) {
     Continuation cont = node.continuation.definition;
     LetPrim letPrim = constifyExpression(node, cont, () {
-      node.receiver.unlink();
+      node.value.unlink();
+      node.typeArguments.forEach((Reference ref) => ref.unlink());
       node.continuation.unlink();
     });
 
@@ -707,19 +708,17 @@
     if (node.isTypeCast) {
       // TODO(jgruber): Add support for `as` casts.
       setValues(nonConstant());
+      return;
     }
 
-    _AbstractValue<T> cell = getValue(node.receiver.definition);
+    _AbstractValue<T> cell = getValue(node.value.definition);
     if (cell.isNothing) {
       return;  // And come back later.
-    } else if (cell.isNonConst) {
-      setValues(nonConstant(cell.type));
-    } else if (node.type.kind == types.TypeKind.INTERFACE) {
+    } else if (cell.isConstant && node.type.kind == types.TypeKind.INTERFACE) {
       // Receiver is a constant, perform is-checks at compile-time.
 
       types.InterfaceType checkedType = node.type;
       ConstantValue constant = cell.constant;
-      // TODO(karlklose): remove call to computeType.
       types.DartType constantType = constant.getType(_dartTypes.coreTypes);
 
       T type = typeSystem.boolType;
@@ -738,6 +737,8 @@
             type);
       }
       setValues(result);
+    } else {
+      setValues(nonConstant(typeSystem.boolType));
     }
   }
 
@@ -829,6 +830,23 @@
     }
   }
 
+  void visitGetStatic(GetStatic node) {
+    setValue(node, nonConstant());
+  }
+
+  void visitSetStatic(SetStatic node) {
+    setReachable(node.body);
+  }
+
+  void visitGetLazyStatic(GetLazyStatic node) {
+    Continuation cont = node.continuation.definition;
+    setReachable(cont);
+
+    assert(cont.parameters.length == 1);
+    Parameter returnValue = cont.parameters[0];
+    setValue(returnValue, nonConstant());
+  }
+
   // Conditions.
 
   void visitIsTrue(IsTrue node) {
@@ -872,14 +890,6 @@
     setReachable(node.body);
   }
 
-  void visitGetStatic(GetStatic node) {
-    setValue(node, nonConstant());
-  }
-
-  void visitSetStatic(SetStatic node) {
-    setReachable(node.body);
-  }
-
   void visitCreateBox(CreateBox node) {
     setValue(node, nonConstant());
   }
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 5469e39..3f92322 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -117,7 +117,6 @@
   bool dumpInfo = false;
   bool allowNativeExtensions = false;
   bool trustTypeAnnotations = false;
-  bool trustPrimitives = false;
   bool checkedMode = false;
   // List of provided options that imply that output is expected.
   List<String> optionsImplyCompilation = <String>[];
@@ -166,6 +165,10 @@
         out = currentDirectory.resolve('out.dart');
         sourceMapOut = currentDirectory.resolve('out.dart.map');
       }
+      diagnosticHandler(null, null, null,
+          "--output-type=dart is deprecated. It will remain available "
+          "in Dart 1.11, but will be removed in Dart 1.12.",
+          api.Diagnostic.WARNING);
     }
     passThrough(argument);
   }
@@ -218,7 +221,6 @@
   }
 
   setTrustPrimitives(String argument) {
-    trustPrimitives = true;
     implyCompilation(argument);
   }
 
@@ -349,6 +351,7 @@
           "Async-await is supported by default.",
           api.Diagnostic.HINT);
     }),
+    new OptionHandler('--enable-null-aware-operators', passThrough),
     new OptionHandler('--enable-enum', (_) {
       diagnosticHandler.info(
           "Option '--enable-enum' is no longer needed. "
@@ -625,7 +628,7 @@
     Generates an out.info.json file with information about the generated code.
     You can inspect the generated file with the viewer at:
         https://dart-lang.github.io/dump-info-visualizer/
-    This feature is currently not supported in combination with the 
+    This feature is currently not supported in combination with the
     '--output-type=dart' option.
 
   --generate-code-with-compile-time-errors
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
index 6af3a4c..5726341 100644
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
@@ -738,7 +738,7 @@
   @override
   Expression visitTypeOperator(tree.TypeOperator exp,
                                BuilderContext<Statement> context) {
-    return new TypeOperator(visitExpression(exp.receiver, context),
+    return new TypeOperator(visitExpression(exp.value, context),
                             exp.operator,
                             TypeGenerator.createType(exp.type));
   }
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart
index bc4867d..a4d445f 100644
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart
@@ -1047,7 +1047,6 @@
 
   void writeParameters(Parameters params) {
     write('(');
-    bool first = true;
     writeEach(',', params.requiredParameters, (Parameter p) {
       if (p.type != null) {
         writeType(p.type);
@@ -1576,4 +1575,4 @@
   StringChunk end(int endIndex) {
     return new StringChunk(previous, quoting, endIndex);
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart b/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
index 04a7b7c..e32f4a5 100644
--- a/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
+++ b/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
@@ -503,7 +503,7 @@
       // }
       // Do not forget to rename them as well.
       FunctionElement constructorFunction = constructor;
-      Link<Element> optionalParameters =
+      List<Element> optionalParameters =
           constructorFunction.functionSignature.optionalParameters;
       for (final argument in send.argumentsNode) {
         NamedArgument named = argument.asNamedArgument();
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index c6ab046..fb26f0c 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -92,8 +92,6 @@
   ElementToJsonVisitor(this.compiler);
 
   void run() {
-    Backend backend = compiler.backend;
-
     dart2jsVersion = compiler.hasBuildId ? compiler.buildId : null;
 
     for (LibraryElement library in compiler.libraryLoader.libraries.toList()) {
@@ -296,7 +294,6 @@
     String inferredReturnType = null;
     String returnType = null;
     String sideEffects = null;
-    String code = "";
 
     StringBuffer emittedCode = compiler.dumpInfoTask.codeOf(element);
     int size = compiler.dumpInfoTask.sizeOf(element);
@@ -559,7 +556,8 @@
 
   void dumpInfoJson(StringSink buffer) {
     JsonEncoder encoder = const JsonEncoder.withIndent('  ');
-    DateTime startToJsonTime = new DateTime.now();
+    Stopwatch stopwatch = new Stopwatch();
+    stopwatch.start();
 
     Map<String, List<Map<String, String>>> holding =
         <String, List<Map<String, String>>>{};
@@ -628,14 +626,12 @@
       'dump_minor_version': '2'
     };
 
-    Duration toJsonDuration = new DateTime.now().difference(startToJsonTime);
-
     Map<String, dynamic> generalProgramInfo = <String, dynamic> {
       'size': _programSize,
       'dart2jsVersion': infoCollector.dart2jsVersion,
       'compilationMoment': new DateTime.now().toString(),
       'compilationDuration': compiler.totalCompileTime.elapsed.toString(),
-      'toJsonDuration': 0,
+      'toJsonDuration': stopwatch.elapsedMilliseconds,
       'dumpInfoDuration': this.timing.toString(),
       'noSuchMethodEnabled': backend.enabledNoSuchMethod,
       'minified': compiler.enableMinification
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index 5301e0b..4a820e0 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -532,7 +532,9 @@
   static bool isInstanceSend(Send send, TreeElements elements) {
     Element element = elements[send];
     if (element == null) return !isClosureSend(send, element);
-    return isInstanceMethod(element) || isInstanceField(element);
+    return isInstanceMethod(element) ||
+           isInstanceField(element) ||
+           send.isConditional;
   }
 
   static bool isClosureSend(Send send, Element element) {
@@ -640,7 +642,7 @@
   static String constructOperatorNameOrNull(String op, bool isUnary) {
     if (isMinusOperator(op)) {
       return isUnary ? 'unary-' : op;
-    } else if (isUserDefinableOperator(op)) {
+    } else if (isUserDefinableOperator(op) || op == '??') {
       return op;
     } else {
       return null;
@@ -666,6 +668,7 @@
     if (identical(op, '&=')) return '&';
     if (identical(op, '^=')) return '^';
     if (identical(op, '|=')) return '|';
+    if (identical(op, '??=')) return '??';
 
     return null;
   }
@@ -973,7 +976,8 @@
 }
 
 /// A function, variable or parameter defined in an executable context.
-abstract class LocalElement extends Element implements TypedElement, Local {
+abstract class LocalElement extends Element
+    implements AstElement, TypedElement, Local {
 }
 
 /// A top level, static or instance field, a formal parameter or local variable.
@@ -1087,8 +1091,8 @@
 
 abstract class FunctionSignature {
   FunctionType get type;
-  Link<FormalElement> get requiredParameters;
-  Link<FormalElement> get optionalParameters;
+  List<FormalElement> get requiredParameters;
+  List<FormalElement> get optionalParameters;
 
   int get requiredParameterCount;
   int get optionalParameterCount;
@@ -1399,8 +1403,8 @@
   void reverseBackendMembers();
 
   Element lookupMember(String memberName);
-  Element lookupSelector(Selector selector);
-  Element lookupSuperSelector(Selector selector);
+  Element lookupByName(Name memberName);
+  Element lookupSuperByName(Name memberName);
 
   Element lookupLocalMember(String memberName);
   Element lookupBackendMember(String memberName);
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index e19d722..e5e4f39 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -825,7 +825,6 @@
 
     if (existing != element) {
       Import existingImport = importers.getImport(existing);
-      Element newElement;
       if (existing.library.isPlatformLibrary &&
           !element.library.isPlatformLibrary) {
         // [existing] is implicitly hidden.
@@ -1749,8 +1748,8 @@
 // [FunctionType].
 // TODO(karlklose): all these lists should have element type [FormalElement].
 class FunctionSignatureX implements FunctionSignature {
-  final Link<Element> requiredParameters;
-  final Link<Element> optionalParameters;
+  final List<Element> requiredParameters;
+  final List<Element> optionalParameters;
   final int requiredParameterCount;
   final int optionalParameterCount;
   final bool optionalParametersAreNamed;
@@ -1758,9 +1757,9 @@
   final FunctionType type;
   final bool hasOptionalParameters;
 
-  FunctionSignatureX({this.requiredParameters: const Link<Element>(),
+  FunctionSignatureX({this.requiredParameters: const <Element>[],
                       this.requiredParameterCount: 0,
-                      Link<Element> optionalParameters: const Link<Element>(),
+                      List<Element> optionalParameters: const <Element>[],
                       this.optionalParameterCount: 0,
                       this.optionalParametersAreNamed: false,
                       this.orderedOptionalParameters: const <Element>[],
@@ -1769,22 +1768,14 @@
         hasOptionalParameters = !optionalParameters.isEmpty;
 
   void forEachRequiredParameter(void function(Element parameter)) {
-    for (Link<Element> link = requiredParameters;
-         !link.isEmpty;
-         link = link.tail) {
-      function(link.head);
-    }
+    requiredParameters.forEach(function);
   }
 
   void forEachOptionalParameter(void function(Element parameter)) {
-    for (Link<Element> link = optionalParameters;
-         !link.isEmpty;
-         link = link.tail) {
-      function(link.head);
-    }
+    optionalParameters.forEach(function);
   }
 
-  Element get firstOptionalParameter => optionalParameters.head;
+  Element get firstOptionalParameter => optionalParameters.first;
 
   void forEachParameter(void function(Element parameter)) {
     forEachRequiredParameter(function);
@@ -1814,8 +1805,8 @@
       if (requiredParameterCount != signature.requiredParameterCount) {
         return false;
       }
-      Set<String> names = optionalParameters.mapToSet(
-          (Element element) => element.name);
+      Set<String> names = optionalParameters.map(
+          (Element element) => element.name).toSet();
       for (Element namedParameter in signature.optionalParameters) {
         if (!names.contains(namedParameter.name)) {
           return false;
@@ -2485,7 +2476,7 @@
   }
 
   /**
-   * Find the first member in the class chain with the given [selector].
+   * 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
@@ -2494,19 +2485,18 @@
    * When called on the implementation element both members declared in the
    * origin and the patch class are returned.
    */
-  Element lookupSelector(Selector selector) {
-    return internalLookupSelector(selector, false);
+  Element lookupByName(Name memberName) {
+    return internalLookupByName(memberName, isSuperLookup: false);
   }
 
-  Element lookupSuperSelector(Selector selector) {
-    return internalLookupSelector(selector, true);
+  Element lookupSuperByName(Name memberName) {
+    return internalLookupByName(memberName, isSuperLookup: true);
   }
 
-  Element internalLookupSelector(Selector selector,
-                                 bool isSuperLookup) {
-    String name = selector.name;
-    bool isPrivate = isPrivateName(name);
-    LibraryElement library = selector.library;
+  Element internalLookupByName(Name memberName, {bool isSuperLookup}) {
+    String name = memberName.text;
+    bool isPrivate = memberName.isPrivate;
+    LibraryElement library = memberName.library;
     for (ClassElement current = isSuperLookup ? superclass : this;
          current != null;
          current = current.superclass) {
@@ -2528,12 +2518,15 @@
         AbstractFieldElement field = member;
         FunctionElement getter = field.getter;
         FunctionElement setter = field.setter;
-        if (selector.isSetter) {
+        if (memberName.isSetter) {
           // Abstract members can be defined in a super class.
-          if (setter != null && !setter.isAbstract) return setter;
+          if (setter != null && !setter.isAbstract) {
+            return setter;
+          }
         } else {
-          assert(selector.isGetter || selector.isCall);
-          if (getter != null && !getter.isAbstract) return getter;
+          if (getter != null && !getter.isAbstract) {
+            return getter;
+          }
         }
       // Abstract members can be defined in a super class.
       } else if (!member.isAbstract) {
diff --git a/pkg/compiler/lib/src/hash/sha1.dart b/pkg/compiler/lib/src/hash/sha1.dart
index 60716a4..02eae83 100644
--- a/pkg/compiler/lib/src/hash/sha1.dart
+++ b/pkg/compiler/lib/src/hash/sha1.dart
@@ -317,29 +317,6 @@
   static const String _encodeTableUrlSafe =
       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
 
-  // Lookup table used for finding Base 64 alphabet index of a given byte.
-  // -2 : Outside Base 64 alphabet.
-  // -1 : '\r' or '\n'
-  //  0 : = (Padding character).
-  // >0 : Base 64 alphabet index of given byte.
-  static const List<int> _decodeTable =
-      const [ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -2, -2, -1, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, 62, -2, 63,
-              52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2,  0, -2, -2,
-              -2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-              15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, 63,
-              -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-              41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 ];
-
   static String bytesToBase64(List<int> bytes,
                               [bool urlSafe = false,
                                bool addLineSeparator = false]) {
diff --git a/pkg/compiler/lib/src/inferrer/concrete_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/concrete_types_inferrer.dart
index c742d51..ed8c156 100644
--- a/pkg/compiler/lib/src/inferrer/concrete_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/concrete_types_inferrer.dart
@@ -233,7 +233,7 @@
     for (BaseType baseType in baseTypes) {
       if (baseType.isClass()) {
         ClassBaseType classBaseType = baseType;
-        if (classBaseType.element.lookupSelector(selector) != null) {
+        if (classBaseType.element.lookupByName(selector.memberName) != null) {
           newBaseTypes.add(baseType);
         }
       } else {
@@ -579,7 +579,11 @@
   }
 
   @override
-  ConcreteType refineReceiver(Selector selector, ConcreteType receiverType) {
+  ConcreteType refineReceiver(Selector selector, ConcreteType receiverType,
+      bool isConditional) {
+    if (isConditional) {
+      throw new UnimplementedError("isConditional in concrete type inferrer");
+    }
     return receiverType.refine(selector, compiler);
   }
 
@@ -1200,7 +1204,6 @@
     listInsert = jsArrayClass.lookupMember('insert');
     listRemoveLast =
         jsArrayClass.lookupMember('removeLast');
-    List<String> typePreservingOps = const ['+', '-', '*'];
     listConstructor =
         compiler.listClass.lookupDefaultConstructor();
     if (listConstructor != null) {
@@ -1238,7 +1241,7 @@
     // TODO(polux): memoize?
     Set<Element> result = new Set<Element>();
     for (ClassElement cls in seenClasses) {
-      Element elem = cls.lookupSelector(selector);
+      Element elem = cls.lookupByName(selector.memberName);
       if (elem != null) {
         result.add(elem.implementation);
       }
@@ -1613,23 +1616,16 @@
         argumentsTypes.positional.iterator;
     // we attach each positional parameter to its corresponding positional
     // argument
-    for (Link<Element> requiredParameters = signature.requiredParameters;
-        !requiredParameters.isEmpty;
-        requiredParameters = requiredParameters.tail) {
-      final Element requiredParameter = requiredParameters.head;
+    for (Element requiredParameter in signature.requiredParameters) {
       // we know moveNext() succeeds because of guard 2
       remainingPositionalArguments.moveNext();
       result[requiredParameter] = remainingPositionalArguments.current;
     }
     if (signature.optionalParametersAreNamed) {
       // we build a map out of the remaining named parameters
-      Link<Element> remainingOptionalParameters = signature.optionalParameters;
       final Map<String, Element> leftOverNamedParameters =
           new Map<String, Element>();
-      for (;
-           !remainingOptionalParameters.isEmpty;
-           remainingOptionalParameters = remainingOptionalParameters.tail) {
-        final Element namedParameter = remainingOptionalParameters.head;
+      for (Element namedParameter in signature.optionalParameters) {
         leftOverNamedParameters[namedParameter.name] = namedParameter;
       }
       // we attach the named arguments to their corresponding optional
@@ -1648,17 +1644,16 @@
     } else { // optional parameters are positional
       // we attach the remaining positional arguments to their corresponding
       // optional parameters
-      Link<Element> remainingOptionalParameters = signature.optionalParameters;
+      Iterator<Element> remainingOptionalParameters =
+          signature.optionalParameters.iterator;
       while (remainingPositionalArguments.moveNext()) {
-        final Element optionalParameter = remainingOptionalParameters.head;
+        // we know this is true because of guard 1
+        remainingOptionalParameters.moveNext();
+        final Element optionalParameter = remainingOptionalParameters.current;
         result[optionalParameter] = remainingPositionalArguments.current;
-        // we know tail is defined because of guard 1
-        remainingOptionalParameters = remainingOptionalParameters.tail;
       }
-      for (;
-           !remainingOptionalParameters.isEmpty;
-           remainingOptionalParameters = remainingOptionalParameters.tail) {
-        handleLeftoverOptionalParameter(remainingOptionalParameters.head);
+      while (remainingOptionalParameters.moveNext()) {
+        handleLeftoverOptionalParameter(remainingOptionalParameters.current);
       }
     }
     return result;
@@ -1692,14 +1687,13 @@
     // don't override these methods. So for 1+2, getSpecialCaseReturnType will
     // be invoked with function = num#+. We use environment.typeOfThis instead.
     ClassElement cls = environment.classOfThis;
+    List<Element> parameters = function.parameters;
     if (cls != null) {
       String name = function.name;
       if ((cls == baseTypes.intBaseType.element
           || cls == baseTypes.doubleBaseType.element)
           && (name == '+' || name == '-' || name == '*')) {
-        Link<Element> parameters =
-            function.functionSignature.requiredParameters;
-        ConcreteType argumentType = environment.lookupType(parameters.head);
+        ConcreteType argumentType = environment.lookupType(parameters.single);
         if (argumentType.getUniqueType() == cls) {
           return singletonConcreteType(new ClassBaseType(cls));
         }
@@ -1707,24 +1701,21 @@
     }
 
     if (function == listIndex || function == listRemoveAt) {
-      Link<Element> parameters = function.functionSignature.requiredParameters;
-      ConcreteType indexType = environment.lookupType(parameters.head);
+      ConcreteType indexType = environment.lookupType(parameters.single);
       if (!indexType.baseTypes.contains(baseTypes.intBaseType)) {
         return emptyConcreteType;
       }
       return listElementType;
     } else if (function == listIndexSet || function == listInsert) {
-      Link<Element> parameters = function.functionSignature.requiredParameters;
-      ConcreteType indexType = environment.lookupType(parameters.head);
+      ConcreteType indexType = environment.lookupType(parameters[0]);
       if (!indexType.baseTypes.contains(baseTypes.intBaseType)) {
         return emptyConcreteType;
       }
-      ConcreteType elementType = environment.lookupType(parameters.tail.head);
+      ConcreteType elementType = environment.lookupType(parameters[1]);
       augmentListElementType(elementType);
       return emptyConcreteType;
     } else if (function == listAdd) {
-      Link<Element> parameters = function.functionSignature.requiredParameters;
-      ConcreteType elementType = environment.lookupType(parameters.head);
+      ConcreteType elementType = environment.lookupType(parameters.single);
       augmentListElementType(elementType);
       return emptyConcreteType;
     } else if (function == listRemoveLast) {
@@ -1819,9 +1810,9 @@
     // When List([length]) is called with some length, we must augment
     // listElementType with {null}.
     if (element == listConstructor) {
-      Link<Element> parameters =
+      List<Element> parameters =
           listConstructor.functionSignature.optionalParameters;
-      ConcreteType lengthType = environment.lookupType(parameters.head);
+      ConcreteType lengthType = environment.lookupType(parameters.first);
       if (lengthType.baseTypes.contains(baseTypes.intBaseType)) {
         augmentListElementType(nullConcreteType);
       }
@@ -2133,7 +2124,7 @@
         if (!baseReceiverType.isNull()) {
           ClassBaseType classBaseType = baseReceiverType;
           ClassElement cls = classBaseType.element;
-          Element getterOrField = cls.lookupSelector(selector);
+          Element getterOrField = cls.lookupByName(selector.memberName);
           if (getterOrField != null) {
             augmentResult(cls, getterOrField.implementation);
           }
@@ -2180,7 +2171,7 @@
         if (!baseReceiverType.isNull()) {
           ClassBaseType classBaseType = baseReceiverType;
           ClassElement cls = classBaseType.element;
-          Element setterOrField = cls.lookupSelector(selector);
+          Element setterOrField = cls.lookupByName(selector.memberName);
           if (setterOrField != null) {
             augmentField(cls, setterOrField.implementation);
           }
@@ -2222,7 +2213,7 @@
         if (!baseReceiverType.isNull()) {
           ClassBaseType classBaseReceiverType = baseReceiverType;
           ClassElement cls = classBaseReceiverType.element;
-          Element method = cls.lookupSelector(selector);
+          Element method = cls.lookupByName(selector.memberName);
           if (method != null) {
             if (method.isFunction) {
               assert(method is FunctionElement);
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
index fa961f2..3314fcd 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -115,8 +115,12 @@
   /**
    * Returns a new receiver type for this [selector] applied to
    * [receiverType].
+   *
+   * The option [isConditional] is true when [selector] was seen in a
+   * conditional send (e.g.  `a?.selector`), in which case the returned type may
+   * be null.
    */
-  T refineReceiver(Selector selector, T receiverType);
+  T refineReceiver(Selector selector, T receiverType, bool isConditional);
 
   /**
    * Returns the internal inferrer representation for [mask].
@@ -441,6 +445,13 @@
     }
     updateLocal() {
       T currentType = locals[local];
+
+      SendSet send = node != null ? node.asSendSet() : null;
+      if (send != null && send.isIfNullAssignment && currentType != null) {
+        // If-null assignments may return either the new or the original value.
+        type = types.addPhiInput(
+            local, types.allocatePhi(locals.block, local, currentType), type);
+      }
       locals[local] = type;
       if (currentType != type) {
         inferrer.recordLocalUpdate(local, type);
@@ -988,6 +999,16 @@
   }
 
   @override
+  T visitIfNotNullDynamicPropertyInvoke(
+      Send node,
+      Node receiver,
+      NodeList arguments,
+      Selector selector,
+      _) {
+    return handleDynamicInvoke(node);
+  }
+
+  @override
   T visitThisPropertyInvoke(
       Send node,
       NodeList arguments,
@@ -997,6 +1018,13 @@
   }
 
   @override
+  T visitIfNull(Send node, Node left, Node right, _) {
+    T firstType = visit(left);
+    T secondType = visit(right);
+    return types.allocateDiamondPhi(firstType, secondType);
+  }
+
+  @override
   T visitLogicalAnd(Send node, Node left, Node right, _) {
     conditionIsSimple = false;
     bool oldAccumulateIsChecks = accumulateIsChecks;
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index dd58fb3..b037c2f 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -365,7 +365,6 @@
   }
 
   void visitMemberTypeInformation(MemberTypeInformation info) {
-    Element element = info.element;
     if (info.isClosurized) {
       bailout('Returned from a closurized method');
     }
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index 941d64d..00ad240 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -155,7 +155,8 @@
     return type != selector.mask;
   }
 
-  TypeMask refineReceiver(Selector selector, TypeMask receiverType) {
+  TypeMask refineReceiver(Selector selector, TypeMask receiverType,
+      bool isConditional) {
     TypeMask newType = compiler.world.allFunctions.receiverType(selector);
     return receiverType.intersection(newType, classWorld);
   }
@@ -1007,8 +1008,19 @@
   @override
   T visitSuperCompoundIndexSet(
       ast.SendSet node,
-      FunctionElement getter,
-      FunctionElement setter,
+      MethodElement getter,
+      MethodElement setter,
+      ast.Node index,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    return handleSuperCompoundIndexSet(node, index, rhs);
+  }
+
+  @override
+  T visitUnresolvedSuperCompoundIndexSet(
+      ast.Send node,
+      Element element,
       ast.Node index,
       op.AssignmentOperator operator,
       ast.Node rhs,
@@ -1020,6 +1032,7 @@
   T visitUnresolvedSuperGetterCompoundIndexSet(
       ast.SendSet node,
       Element element,
+      MethodElement setter,
       ast.Node index,
       op.AssignmentOperator operator,
       ast.Node rhs,
@@ -1030,7 +1043,7 @@
   @override
   T visitUnresolvedSuperSetterCompoundIndexSet(
       ast.SendSet node,
-      FunctionElement getter,
+      MethodElement getter,
       Element element,
       ast.Node index,
       op.AssignmentOperator operator,
@@ -1040,9 +1053,21 @@
   }
 
   @override
+  T visitUnresolvedSuperIndexPrefix(
+      ast.Send node,
+      Element element,
+      ast.Node index,
+      op.IncDecOperator operator,
+      _) {
+    T indexType = visit(index);
+    return handleCompoundPrefixPostfix(node, superType, indexType);
+  }
+
+  @override
   T visitUnresolvedSuperGetterIndexPrefix(
       ast.SendSet node,
       Element element,
+      MethodElement setter,
       ast.Node index,
       op.IncDecOperator operator,
       _) {
@@ -1053,7 +1078,18 @@
   @override
   T visitUnresolvedSuperSetterIndexPrefix(
       ast.SendSet node,
-      FunctionElement getter,
+      MethodElement getter,
+      Element element,
+      ast.Node index,
+      op.IncDecOperator operator,
+      _) {
+    T indexType = visit(index);
+    return handleCompoundPrefixPostfix(node, superType, indexType);
+  }
+
+  @override
+  T visitUnresolvedSuperIndexPostfix(
+      ast.Send node,
       Element element,
       ast.Node index,
       op.IncDecOperator operator,
@@ -1066,6 +1102,7 @@
   T visitUnresolvedSuperGetterIndexPostfix(
       ast.SendSet node,
       Element element,
+      MethodElement setter,
       ast.Node index,
       op.IncDecOperator operator,
       _) {
@@ -1076,7 +1113,7 @@
   @override
   T visitUnresolvedSuperSetterIndexPostfix(
       ast.SendSet node,
-      FunctionElement getter,
+      MethodElement getter,
       Element element,
       ast.Node index,
       op.IncDecOperator operator,
@@ -1371,6 +1408,18 @@
       MethodElement method,
       ast.Node argument,
       _) {
+    // TODO(johnniwinther): Special case ==.
+    return handleSuperMethodInvoke(
+        node, method, analyzeArguments(node.arguments));
+  }
+
+  @override
+  T visitSuperNotEquals(
+      ast.Send node,
+      MethodElement method,
+      ast.Node argument,
+      _) {
+    // TODO(johnniwinther): Special case !=.
     return handleSuperMethodInvoke(
         node, method, analyzeArguments(node.arguments));
   }
@@ -1656,10 +1705,7 @@
           compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
       sideEffects.add(nativeBehavior.sideEffects);
       return inferrer.typeOfNativeBehavior(nativeBehavior);
-    } else if (name == 'JS_NULL_CLASS_NAME'
-               || name == 'JS_OBJECT_CLASS_NAME'
-               || name == 'JS_OPERATOR_AS_PREFIX'
-               || name == 'JS_STRING_CONCAT') {
+    } else if (name == 'JS_OPERATOR_AS_PREFIX' || name == 'JS_STRING_CONCAT') {
       return types.stringType;
     } else {
       sideEffects.setAllSideEffects();
@@ -1726,6 +1772,15 @@
   }
 
   @override
+  T visitIfNotNullDynamicPropertyGet(
+      ast.Send node,
+      ast.Node receiver,
+      Selector selector,
+      _) {
+    return handleDynamicGet(node);
+  }
+
+  @override
   T visitLocalVariableGet(
       ast.Send node,
       LocalVariableElement variable,
@@ -1910,12 +1965,14 @@
     // 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.
-    if (node.asSend() != null) {
-      ast.Node receiver = node.asSend().receiver;
+    ast.Send send = node.asSend();
+    if (send != null) {
+      ast.Node receiver = send.receiver;
       if (receiver != null) {
         Element element = elements[receiver];
         if (Elements.isLocal(element) && !capturedVariables.contains(element)) {
-          T refinedType = types.refineReceiver(selector, receiverType);
+          T refinedType = types.refineReceiver(selector, receiverType,
+              send.isConditional);
           locals.update(element, refinedType, node);
         }
       }
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 2b63c0c..b812859 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -27,6 +27,8 @@
 import '../tree/tree.dart' as ast
     show DartString,
          Node,
+         Send,
+         SendSet,
          TryStatement;
 import '../types/types.dart'
     show ContainerTypeMask,
@@ -248,9 +250,17 @@
     return info.type != selector.mask;
   }
 
-  TypeInformation refineReceiver(Selector selector, TypeInformation receiver) {
+  TypeInformation refineReceiver(Selector selector, TypeInformation receiver,
+      bool isConditional) {
     if (receiver.type.isExact) return receiver;
     TypeMask otherType = compiler.world.allFunctions.receiverType(selector);
+    // Conditional sends (a?.b) can still narrow the possible types of `a`,
+    // however, we still need to consider that `a` may be null.
+    if (isConditional) {
+      // Note: we don't check that receiver.type.isNullable here because this is
+      // called during the graph construction.
+      otherType = otherType.nullable();
+    }
     // If this is refining to nullable subtype of `Object` just return
     // the receiver. We know the narrowing is useless.
     if (otherType.isNullable && otherType.containsAll(classWorld)) {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index a12b342..7df1cbb 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -897,7 +897,7 @@
 
     // Walk over the found targets, and compute the joined union type mask
     // for all these targets.
-    return inferrer.types.joinTypeMasks(targets.map((element) {
+    TypeMask result = inferrer.types.joinTypeMasks(targets.map((element) {
       // If [canReachAll] is true, then we are iterating over all
       // targets that satisfy the untyped selector. We skip the return
       // type of the targets that can only be reached through
@@ -942,6 +942,15 @@
         return inferrer.typeOfElementWithSelector(element, typedSelector).type;
       }
     }));
+
+    if (call is ast.Send) {
+      ast.Send send = call;
+      if (send.isConditional && receiver.type.isNullable) {
+        // Conditional sends (e.g. `a?.b`) may be null if the receiver is null.
+        result = result.nullable();
+      }
+    }
+    return result;
   }
 
   void giveUp(TypeGraphInferrerEngine inferrer, {bool clearAssignments: true}) {
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index 601256d..e7b23ea 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -5,7 +5,9 @@
 library dart2js.source_information;
 
 import '../dart2jslib.dart' show SourceSpan, MessageKind;
-import '../elements/elements.dart' show AstElement;
+import '../elements/elements.dart' show
+    AstElement,
+    LocalElement;
 import '../scanner/scannerlib.dart' show Token;
 import '../tree/tree.dart' show Node;
 import '../js/js.dart' show JavaScriptNodeSourceInformation;
@@ -103,7 +105,7 @@
 
     AstElement implementation = element.implementation;
     SourceFile sourceFile = implementation.compilationUnit.script.file;
-    String name = element.name;
+    String name = computeElementNameForSourceMaps(element);
     Node node = implementation.node;
     Token beginToken;
     Token endToken;
@@ -156,7 +158,7 @@
 
   StartEndSourceInformationBuilder(AstElement element)
       : sourceFile = element.compilationUnit.script.file,
-        name = element.name;
+        name = computeElementNameForSourceMaps(element);
 
   SourceInformation buildDeclaration(AstElement element) {
     return StartEndSourceInformation.computeSourceInformation(element);
@@ -339,7 +341,7 @@
 
   PositionSourceInformationBuilder(AstElement element)
       : sourceFile = element.implementation.compilationUnit.script.file,
-        name = element.name;
+        name = computeElementNameForSourceMaps(element);
 
   SourceInformation buildDeclaration(AstElement element) {
     if (element.isSynthesized) {
@@ -379,3 +381,32 @@
     return new PositionSourceInformationBuilder(element);
   }
 }
+
+/// Compute the source map name for [element].
+String computeElementNameForSourceMaps(AstElement element) {
+  if (element.isClosure) {
+    return computeElementNameForSourceMaps(element.enclosingElement);
+  } 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>';
+    }
+    return '${computeElementNameForSourceMaps(local.executableContext)}.$name';
+  } else if (element.enclosingClass != null) {
+    if (element.enclosingClass.isClosure) {
+      return computeElementNameForSourceMaps(element.enclosingClass);
+    }
+    return '${element.enclosingClass.name}.${element.name}';
+  } else {
+    return element.name;
+  }
+}
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 986a313..3bc8c0f 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -1655,18 +1655,6 @@
         element == jsUnmodifiableArrayClass;
   }
 
-  /// Return [true] if the class is represented by a native JavaSCript type in
-  /// the generated code.
-  bool isNativePrimitiveType(ClassElement cls ) {
-    // TODO(karlklose): cleanup/merge with hasDirectCheck, when the rest of the
-    // checks are implemented in the CPS IR.
-    return cls == compiler.intClass ||
-        cls == compiler.numClass ||
-        cls == compiler.doubleClass ||
-        cls == compiler.boolClass ||
-        cls == compiler.stringClass;
-  }
-
   bool mayGenerateInstanceofCheck(DartType type) {
     // We can use an instanceof check for raw types that have no subclass that
     // is mixed-in or in an implements clause.
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index 2998a5b..c133788 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -15,8 +15,6 @@
 import '../../dart2jslib.dart';
 import '../../dart_types.dart';
 
-part 'type_test_emitter.dart';
-
 class CodegenBailout {
   final tree_ir.Node node;
   final String reason;
@@ -27,8 +25,7 @@
 }
 
 class CodeGenerator extends tree_ir.StatementVisitor
-                    with tree_ir.ExpressionVisitor<js.Expression>,
-                         TypeTestEmitter {
+                    with tree_ir.ExpressionVisitor<js.Expression> {
   final CodegenRegistry registry;
 
   final Glue glue;
@@ -306,7 +303,6 @@
   @override
   js.Expression visitLiteralList(tree_ir.LiteralList node) {
     registry.registerInstantiatedClass(glue.listClass);
-    int length = node.values.length;
     List<js.Expression> entries = node.values.map(visitExpression).toList();
     return new js.ArrayInitializer(entries);
   }
@@ -354,14 +350,40 @@
 
   @override
   js.Expression visitTypeOperator(tree_ir.TypeOperator node) {
+    js.Expression value = visitExpression(node.value);
+    List<js.Expression> typeArguments =
+        node.typeArguments.map(visitExpression).toList();
     if (!node.isTypeTest) {
       giveup(node, 'type casts not implemented.');
     }
     DartType type = node.type;
-    if (type is InterfaceType && type.isRaw) {
+    // Note that the trivial (but special) cases of Object, dynamic, and Null
+    // are handled at build-time and must not occur in a TypeOperator.
+    assert(!type.isObject && !type.isDynamic);
+    if (type is InterfaceType) {
       glue.registerIsCheck(type, registry);
-      js.Expression value = visitExpression(node.receiver);
-      return emitSubtypeTest(node, value, type);
+      ClassElement clazz = type.element;
+
+      // We use the helper:
+      //
+      //     checkSubtype(value, $isT, typeArgs, $asT)
+      //
+      // Any of the last two arguments may be null if there are no type
+      // arguments, and/or if no substitution is required.
+
+      js.Expression isT = js.string(glue.getTypeTestTag(type));
+
+      js.Expression typeArgumentArray = typeArguments.isNotEmpty
+          ? new js.ArrayInitializer(typeArguments)
+          : new js.LiteralNull();
+
+      js.Expression asT = glue.hasStrictSubtype(clazz)
+          ? js.string(glue.getTypeSubstitutionTag(clazz))
+          : new js.LiteralNull();
+
+      return buildStaticHelperInvocation(
+          glue.getCheckSubtype(),
+          [value, isT, typeArgumentArray, asT]);
     }
     return giveup(node, 'type check unimplemented for $type.');
   }
@@ -590,13 +612,20 @@
   @override
   js.Expression visitGetStatic(tree_ir.GetStatic node) {
     assert(node.element is FieldElement || node.element is FunctionElement);
-    if (node.element is FieldElement) {
-      registry.registerStaticUse(node.element.declaration);
-      return glue.staticFieldAccess(node.element);
-    } else {
+    if (node.element is FunctionElement) {
+      // Tear off a method.
       registry.registerGetOfStaticFunction(node.element.declaration);
       return glue.isolateStaticClosureAccess(node.element);
     }
+    if (glue.isLazilyInitialized(node.element)) {
+      // Read a lazily initialized field.
+      registry.registerStaticUse(node.element.declaration);
+      js.Expression getter = glue.isolateLazyInitializerAccess(node.element);
+      return new js.Call(getter, [], sourceInformation: node.sourceInformation);
+    }
+    // Read an eagerly initialized field.
+    registry.registerStaticUse(node.element.declaration);
+    return glue.staticFieldAccess(node.element);
   }
 
   @override
@@ -629,10 +658,10 @@
     ClassElement context = node.variable.element.enclosingClass;
     js.Expression index = js.number(glue.getTypeVariableIndex(node.variable));
     if (glue.needsSubstitutionForTypeVariableAccess(context)) {
-      js.Expression substitution = glue.getSubstitutionName(context);
+      js.Expression typeName = glue.getRuntimeTypeName(context);
       return buildStaticHelperInvocation(
-          glue.getTypeArgumentWithSubstitution(),
-          [visitExpression(node.target), substitution, index]);
+          glue.getRuntimeTypeArgument(),
+          [visitExpression(node.target), typeName, index]);
     } else {
       return buildStaticHelperInvocation(
           glue.getTypeArgumentByIndex(),
diff --git a/pkg/compiler/lib/src/js_backend/codegen/glue.dart b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
index 27c568e..cb87354 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
@@ -60,6 +60,14 @@
     return _backend.emitter.staticFieldAccess(element);
   }
 
+  js.Expression isolateLazyInitializerAccess(FieldElement element) {
+    return _backend.emitter.isolateLazyInitializerAccess(element);
+  }
+
+  bool isLazilyInitialized(FieldElement element) {
+    return _backend.constants.lazyStatics.contains(element);
+  }
+
   String safeVariableName(String name) {
     return _namer.safeVariableName(name);
   }
@@ -151,7 +159,7 @@
     return _backend.getRuntimeTypeToString();
   }
 
-  FunctionElement getTypeArgumentWithSubstitution() {
+  FunctionElement getRuntimeTypeArgument() {
     return _backend.getGetRuntimeTypeArgument();
   }
 
@@ -163,8 +171,12 @@
     return _backend.getSetRuntimeTypeInfo();
   }
 
-  js.Expression getSubstitutionName(ClassElement cls) {
-    return js.string(_namer.substitutionName(cls));
+  FunctionElement getCheckSubtype() {
+    return _backend.getCheckSubtype();
+  }
+
+  js.Expression getRuntimeTypeName(ClassElement cls) {
+    return js.string(_namer.runtimeTypeName(cls));
   }
 
   int getTypeVariableIndex(TypeVariableType variable) {
@@ -191,33 +203,24 @@
     return representation;
   }
 
-  bool isNativePrimitiveType(DartType type) {
-    if (type is! InterfaceType) return false;
-    return _backend.isNativePrimitiveType(type.element);
-  }
-
   void registerIsCheck(DartType type, Registry registry) {
     _enqueuer.registerIsCheck(type, registry);
     _backend.registerIsCheckForCodegen(type, _enqueuer, registry);
   }
 
-  bool isIntClass(ClassElement cls) => cls == _compiler.intClass;
-
-  bool isStringClass(ClassElement cls) => cls == _compiler.stringClass;
-
-  bool isBoolClass(ClassElement cls) => cls == _compiler.boolClass;
-
-  bool isNumClass(ClassElement cls) => cls == _compiler.numClass;
-
-  bool isDoubleClass(ClassElement cls) => cls == _compiler.doubleClass;
-
   String getTypeTestTag(DartType type) {
     return _backend.namer.operatorIsType(type);
   }
 
+  String getTypeSubstitutionTag(ClassElement element) {
+    return _backend.namer.substitutionName(element);
+  }
+
   bool operatorEqHandlesNullArgument(FunctionElement element) {
     return _backend.operatorEqHandlesNullArgument(element);
   }
 
-  bool isListClass(ClassElement cls) => cls == _compiler.listClass;
+  bool hasStrictSubtype(ClassElement element) {
+    return _compiler.world.hasAnyStrictSubtype(element);
+  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/task.dart b/pkg/compiler/lib/src/js_backend/codegen/task.dart
index 3befc85..ab69b01 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/task.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/task.dart
@@ -13,7 +13,6 @@
 import '../../constants/constant_system.dart';
 import '../../dart2jslib.dart';
 import '../../cps_ir/cps_ir_nodes.dart' as cps;
-import '../../cps_ir/cps_ir_builder.dart';
 import '../../cps_ir/cps_ir_integrity.dart';
 import '../../cps_ir/cps_ir_builder_task.dart';
 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir;
@@ -23,7 +22,6 @@
 import '../../js/js.dart' as js;
 import '../../io/source_information.dart' show SourceInformationFactory;
 import '../../tree_ir/tree_ir_builder.dart' as tree_builder;
-import '../../dart_backend/backend_ast_emitter.dart' as backend_ast_emitter;
 import '../../cps_ir/optimizers.dart';
 import '../../cps_ir/optimizers.dart' as cps_opt;
 import '../../tracer.dart';
@@ -104,8 +102,7 @@
 
   cps.FunctionDefinition compileToCpsIR(AstElement element) {
     // TODO(sigurdm): Support these constructs.
-    if (element.isNative ||
-        element.isField) {
+    if (element.isNative) {
       giveUp('unsupported element kind: ${element.name}:${element.kind}');
     }
 
diff --git a/pkg/compiler/lib/src/js_backend/codegen/type_test_emitter.dart b/pkg/compiler/lib/src/js_backend/codegen/type_test_emitter.dart
deleted file mode 100644
index 959756f..0000000
--- a/pkg/compiler/lib/src/js_backend/codegen/type_test_emitter.dart
+++ /dev/null
@@ -1,92 +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 code_generator;
-
-abstract class TypeTestEmitter {
-  giveup(node, reason);
-  Glue get glue;
-
-  js.Expression emitSubtypeTest(tree_ir.Node node,
-                                js.Expression value,
-                                DartType type) {
-    return glue.isNativePrimitiveType(type)
-        ? emitNativeSubtypeTest(node, value, type.element)
-        : emitGeneralSubtypeTest(node, value, type);
-  }
-
-  js.Expression emitNativeSubtypeTest(tree_ir.Node node,
-                                      js.Expression value,
-                                      ClassElement cls) {
-    if (glue.isIntClass(cls)) {
-      return _emitIntCheck(value);
-    } else if (glue.isStringClass(cls)) {
-      return _emitTypeofCheck(value, 'string');
-    } else if (glue.isBoolClass(cls)) {
-      return _emitTypeofCheck(value, 'boolean');
-    } else if (glue.isNumClass(cls) || glue.isDoubleClass(cls)) {
-      return _emitNumCheck(value);
-    } else {
-      return giveup(value, 'type check unimplemented for ${cls.name}.');
-    }
-  }
-
-  js.Expression _emitNativeListCheck(js.Expression value) {
-        return identical(
-            new js.PropertyAccess.field(value, 'constructor'),
-            new js.VariableUse('Array'));
-  }
-
-  js.Expression emitPropertyTypeTest(tree_ir.Node node,
-                                     js.Expression value,
-                                     InterfaceType type) {
-    return and(
-        boolify(value),
-        boolify(new js.PropertyAccess.field(value, glue.getTypeTestTag(type))));
-  }
-
-  js.Expression emitGeneralSubtypeTest(tree_ir.Node node,
-                                       js.Expression value,
-                                       InterfaceType type) {
-    if (glue.isListClass(type.element)) {
-      return or(_emitNativeListCheck(value),
-          emitPropertyTypeTest(node, value, type));
-    }
-    return emitPropertyTypeTest(node, value, type);
-  }
-
-  js.Expression _emitNumCheck(js.Expression value) {
-    return _emitTypeofCheck(value, 'number');
-  }
-
-  js.Expression _emitBigIntCheck(js.Expression value) {
-    return js.js('Math.floor(#) === #', [value, value]);
-  }
-
-  js.Expression _emitIntCheck(js.Expression value) {
-    return and(_emitNumCheck(value), _emitBigIntCheck(value));
-  }
-
-  js.Expression _emitTypeofCheck(js.Expression value, String type) {
-    return identical(new js.Prefix("typeof", value), js.string(type));
-  }
-
-  // Static helpers to generate common JavaScript expressions.
-
-  static js.Expression or(js.Expression left, js.Expression right) {
-    return new js.Binary('||', left, right);
-  }
-
-  static js.Expression and(js.Expression left, js.Expression right) {
-    return new js.Binary('&&', left, right);
-  }
-
-  static js.Expression identical(js.Expression left, js.Expression right) {
-    return new js.Binary('===', left, right);
-  }
-
-  static js.Expression boolify(js.Expression value) {
-    return new js.Prefix('!!', value);
-  }
-}
diff --git a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
index fab6a45..24aec5a 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
@@ -193,7 +193,7 @@
       if (stackTraceParameter.hasAtLeastOneUse) {
         Parameter stackTraceValue = new Parameter(null);
         stackTraceValue.substituteFor(stackTraceParameter);
-        insertStaticCall(_glue.getTraceFromException(), [exceptionValue],
+        insertStaticCall(_glue.getTraceFromException(), [_exceptionParameter],
             stackTraceValue, body);
       }
     }
@@ -292,4 +292,8 @@
     node.falseContinuation.unlink();
     parent.body = newNode;
   }
+
+  processInterceptor(Interceptor node) {
+    _glue.registerSpecializedGetInterceptor(node.interceptedClasses);
+  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 1b3e95f..f01f0d0 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -296,11 +296,11 @@
         backend.classNeedsRti(type.element)) {
       InterfaceType interface = type;
       RuntimeTypes rti = backend.rti;
-      Iterable<String> arguments = interface.typeArguments
+      Iterable<jsAst.Expression> arguments = interface.typeArguments
           .map((DartType type) =>
-              rti.getTypeRepresentationWithHashes(type, (_){}));
+              rti.getTypeRepresentationWithPlaceholders(type, (_){}));
       jsAst.Expression argumentList =
-          new jsAst.LiteralString('[${arguments.join(', ')}]');
+          new jsAst.ArrayInitializer(arguments.toList());
       return new jsAst.Call(getHelperProperty(backend.getSetRuntimeTypeInfo()),
                             [value, argumentList]);
     }
diff --git a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
index 547905d..38d4704 100644
--- a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
+++ b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
@@ -140,7 +140,7 @@
       // If the implementation is 'noSuchMethod(x) => super.noSuchMethod(x);'
       // then it is in the same category as the super call.
       Element superCall = element.enclosingClass
-          .lookupSuperSelector(_compiler.noSuchMethodSelector);
+          .lookupSuperByName(_compiler.noSuchMethodSelector.memberName);
       NsmCategory category = _categorizeImpl(superCall);
       switch(category) {
         case NsmCategory.DEFAULT:
diff --git a/pkg/compiler/lib/src/js_backend/patch_resolver.dart b/pkg/compiler/lib/src/js_backend/patch_resolver.dart
index 84d67cc..34a5014 100644
--- a/pkg/compiler/lib/src/js_backend/patch_resolver.dart
+++ b/pkg/compiler/lib/src/js_backend/patch_resolver.dart
@@ -34,11 +34,13 @@
   }
 
   void checkMatchingPatchParameters(FunctionElement origin,
-                                    Link<Element> originParameters,
-                                    Link<Element> patchParameters) {
-    while (!originParameters.isEmpty) {
-      ParameterElementX originParameter = originParameters.head;
-      ParameterElementX patchParameter = patchParameters.head;
+                                    List<Element> originParameters,
+                                    List<Element> patchParameters) {
+
+    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) {
@@ -86,16 +88,12 @@
               {'parameterName': patchParameter.name});
         }
       }
-
-      originParameters = originParameters.tail;
-      patchParameters = patchParameters.tail;
     }
   }
 
   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;
@@ -155,4 +153,4 @@
     }
   }
 
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index e14487f..2b13f03 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -550,15 +550,24 @@
     }
   }
 
-  String getTypeRepresentationWithHashes(DartType type,
-                                         OnVariableCallback onVariable) {
+  /**
+   * Returns a [jsAst.Expression] representing the given [type]. Type
+   * variables are replaced by placeholders in the ast.
+   *
+   * [firstPlaceholderIndex] is the index to use for the first placeholder.
+   * This is useful if the returned [jsAst.Expression] is only part of a
+   * larger template. By default, indexing starts with 0.
+   */
+  jsAst.Expression getTypeRepresentationWithPlaceholders(DartType type,
+      OnVariableCallback onVariable, {int firstPlaceholderIndex : 0}) {
     // Create a type representation.  For type variables call the original
     // callback for side effects and return a template placeholder.
+    int positions = firstPlaceholderIndex;
     jsAst.Expression representation = getTypeRepresentation(type, (variable) {
       onVariable(variable);
-      return new jsAst.LiteralString('#');
+      return new jsAst.InterpolatedExpression(positions++);
     });
-    return jsAst.prettyPrint(representation, compiler).buffer.toString();
+    return representation;
   }
 
   jsAst.Expression getTypeRepresentation(
@@ -655,11 +664,9 @@
   }
 
   jsAst.Expression visitList(List<DartType> types, {jsAst.Expression head}) {
-    int index = 0;
     List<jsAst.Expression> elements = <jsAst.Expression>[];
     if (head != null) {
       elements.add(head);
-      index++;
     }
     for (DartType type in types) {
       jsAst.Expression element = visit(type);
diff --git a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
index 52d00c4..26e38a9 100644
--- a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
+++ b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
@@ -10,7 +10,6 @@
 class TypeVariableHandler {
   final Compiler _compiler;
   FunctionElement _typeVariableConstructor;
-  CompileTimeConstantEvaluator _evaluator;
 
   /**
    * Set to 'true' on first encounter of a class with type variables.
diff --git a/pkg/compiler/lib/src/js_emitter/native_emitter.dart b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
index 5749e79..d6d39be 100644
--- a/pkg/compiler/lib/src/js_emitter/native_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
@@ -314,8 +314,6 @@
     // must be turned into a JS call to:
     //   foo(null, y).
 
-    ClassElement classElement = member.enclosingClass;
-
     List<jsAst.Statement> statements = <jsAst.Statement>[];
     potentiallyConvertDartClosuresToJs(statements, member, stubParameters);
 
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart
index aeeddc3..1cea1f3 100644
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart
@@ -140,27 +140,20 @@
         return js.js.expressionTemplateYielding(
             typeAccess(_compiler.objectClass));
 
-      case JsBuiltin.classNameFromIsCheckProperty:
+      case JsBuiltin.isCheckPropertyToJsConstructorName:
         int isPrefixLength = namer.operatorIsPrefix.length;
         return js.js.expressionTemplateFor('#.substring($isPrefixLength)');
 
       case JsBuiltin.isFunctionType:
         return _backend.rti.representationGenerator.templateForIsFunctionType;
 
-      case JsBuiltin.isFunctionTypeLiteral:
-        String functionClassName =
-            _backend.namer.runtimeTypeName(_compiler.functionClass);
-
-        return js.js.expressionTemplateFor(
-            '#.$typeNameProperty === "$functionClassName"');
-
-      case JsBuiltin.typeName:
+      case JsBuiltin.rawRtiToJsConstructorName:
         return js.js.expressionTemplateFor("#.$typeNameProperty");
 
       case JsBuiltin.rawRuntimeType:
         return js.js.expressionTemplateFor("#.constructor");
 
-      case JsBuiltin.createFunctionType:
+      case JsBuiltin.createFunctionTypeRti:
         return _backend.rti.representationGenerator
             .templateForCreateFunctionType;
 
@@ -170,6 +163,24 @@
         String isPrefix = namer.operatorIsPrefix;
         return js.js.expressionTemplateFor("('$isPrefix' + #) in #.prototype");
 
+      case JsBuiltin.isFunctionTypeRti:
+        String functionClassName =
+            _backend.namer.runtimeTypeName(_compiler.functionClass);
+        return js.js.expressionTemplateFor(
+            '#.$typeNameProperty === "$functionClassName"');
+
+      case JsBuiltin.isNullTypeRti:
+        String nullClassName =
+            _backend.namer.runtimeTypeName(_compiler.nullClass);
+        return js.js.expressionTemplateFor(
+            '#.$typeNameProperty === "$nullClassName"');
+
+      case JsBuiltin.isDartObjectTypeRti:
+        String dartObjectClassName =
+            _backend.namer.runtimeTypeName(_compiler.objectClass);
+        return js.js.expressionTemplateFor(
+            '#.$typeNameProperty === "$dartObjectClassName"');
+
       case JsBuiltin.getMetadata:
         return _emitter.templateForReadMetadata;
 
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
index dd2c214..d573580 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
@@ -16,7 +16,7 @@
 
   // TODO(johnniwinther): Wrap these fields in a caching strategy.
   final Set<ConstantValue> cachedEmittedConstants;
-  final CodeBuffer cachedEmittedConstantsBuffer = new CodeBuffer();
+  final List<jsAst.Statement> cachedEmittedConstantsAst = <jsAst.Statement>[];
   final Map<Element, ClassBuilder> cachedClassBuilders;
   final Set<Element> cachedElements;
 
@@ -37,9 +37,6 @@
   // The full code that is written to each hunk part-file.
   Map<OutputUnit, CodeOutput> outputBuffers = new Map<OutputUnit, CodeOutput>();
 
-  /** Shorter access to [isolatePropertiesName]. Both here in the code, as
-      well as in the generated code. */
-  String isolateProperties;
   String classesCollector;
   Set<ClassElement> get neededClasses => task.neededClasses;
   Map<OutputUnit, List<ClassElement>> get outputClassLists
@@ -123,10 +120,6 @@
     _cspPrecompiledConstructorNames.clear();
   }
 
-  void addComment(String comment, CodeOutput output) {
-    output.addBuffer(jsAst.prettyPrint(js.comment(comment), compiler));
-  }
-
   @override
   bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
     if (constant.isFunction) return true;    // Already emitted.
@@ -202,7 +195,7 @@
   static const String FIELD_NAMES_PROPERTY_NAME = r"$__fields__";
 
   /// For deferred loading we communicate the initializers via this global var.
-  final String deferredInitializers = r"$dart_deferred_initializers";
+  final String deferredInitializers = r"$dart_deferred_initializers$";
 
   /// Contains the global state that is needed to initialize and load a
   /// deferred library.
@@ -276,26 +269,20 @@
         return jsAst.js.expressionTemplateYielding(
             typeAccess(compiler.objectClass));
 
-      case JsBuiltin.classNameFromIsCheckProperty:
+      case JsBuiltin.isCheckPropertyToJsConstructorName:
         int isPrefixLength = namer.operatorIsPrefix.length;
         return jsAst.js.expressionTemplateFor('#.substring($isPrefixLength)');
 
       case JsBuiltin.isFunctionType:
         return backend.rti.representationGenerator.templateForIsFunctionType;
 
-      case JsBuiltin.isFunctionTypeLiteral:
-        String functionClassName =
-            backend.namer.runtimeTypeName(compiler.functionClass);
-        return jsAst.js.expressionTemplateFor(
-          '#.$typeNameProperty === "$functionClassName"');
-
-      case JsBuiltin.typeName:
+      case JsBuiltin.rawRtiToJsConstructorName:
         return jsAst.js.expressionTemplateFor("#.$typeNameProperty");
 
       case JsBuiltin.rawRuntimeType:
         return jsAst.js.expressionTemplateFor("#.constructor");
 
-      case JsBuiltin.createFunctionType:
+      case JsBuiltin.createFunctionTypeRti:
         return backend.rti.representationGenerator
             .templateForCreateFunctionType;
 
@@ -306,6 +293,24 @@
         return jsAst.js.expressionTemplateFor(
             "('$isPrefix' + #) in #.prototype");
 
+      case JsBuiltin.isFunctionTypeRti:
+        String functionClassName =
+            backend.namer.runtimeTypeName(compiler.functionClass);
+        return jsAst.js.expressionTemplateFor(
+            '#.$typeNameProperty === "$functionClassName"');
+
+      case JsBuiltin.isDartObjectTypeRti:
+        String objectClassName =
+            backend.namer.runtimeTypeName(compiler.objectClass);
+        return jsAst.js.expressionTemplateFor(
+            '#.$typeNameProperty === "$objectClassName"');
+
+      case JsBuiltin.isNullTypeRti:
+        String nullClassName =
+            backend.namer.runtimeTypeName(compiler.nullClass);
+        return jsAst.js.expressionTemplateFor(
+            '#.$typeNameProperty === "$nullClassName"');
+
       case JsBuiltin.getMetadata:
         String metadataAccess =
             generateEmbeddedGlobalAccessString(embeddedNames.METADATA);
@@ -343,11 +348,6 @@
     return interceptorEmitter.generateInterceptedNamesSet();
   }
 
-  void emitFinishIsolateConstructorInvocation(CodeOutput output) {
-    String isolate = namer.isolateName;
-    output.add("$isolate = $finishIsolateConstructorName($isolate)$N");
-  }
-
   /// In minified mode we want to keep the name for the most common core types.
   bool _isNativeTypeNeedingReflectionName(Element element) {
     if (!element.isClass) return false;
@@ -471,21 +471,27 @@
 
   jsAst.Statement buildCspPrecompiledFunctionFor(
       OutputUnit outputUnit) {
-    // TODO(ahe): Compute a hash code.
-    // TODO(sigurdm): Avoid this precompiled function. Generated
-    // constructor-functions and getter/setter functions can be stored in the
-    // library-description table. Setting properties on these can be moved to
-    // finishClasses.
-    return js.statement('''
-      # = function (\$collectedClasses) {
-        var \$desc;
-        #;
-        return #;
-      };''',
-        [generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED),
-         cspPrecompiledFunctionFor(outputUnit),
-         new jsAst.ArrayInitializer(
-             cspPrecompiledConstructorNamesFor(outputUnit))]);
+    if (compiler.useContentSecurityPolicy) {
+      // TODO(ahe): Compute a hash code.
+      // TODO(sigurdm): Avoid this precompiled function. Generated
+      // constructor-functions and getter/setter functions can be stored in the
+      // library-description table. Setting properties on these can be moved to
+      // finishClasses.
+      return js.statement(r"""
+        #precompiled = function ($collectedClasses$) {
+          #norename;
+          var $desc;
+          #functions;
+          return #result;
+        };""",
+        {'norename': new jsAst.Comment("// ::norenaming:: "),
+         'precompiled': generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED),
+         'functions': cspPrecompiledFunctionFor(outputUnit),
+         'result': new jsAst.ArrayInitializer(
+               cspPrecompiledConstructorNamesFor(outputUnit))});
+    } else {
+      return js.comment("Constructors are generated at runtime.");
+    }
   }
 
   void assembleClass(Class cls, ClassBuilder enclosingBuilder,
@@ -526,19 +532,18 @@
     }
   }
 
-  void emitStaticNonFinalFieldInitializations(CodeOutput output,
-                                              OutputUnit outputUnit) {
-    void emitInitialization(Element element, jsAst.Expression initialValue) {
-      jsAst.Expression init =
-        js('$isolateProperties.# = #',
-            [namer.globalPropertyName(element), initialValue]);
-      output.addBuffer(jsAst.prettyPrint(init, compiler,
-                                         monitor: compiler.dumpInfoTask));
-      output.add('$N');
+  jsAst.Statement buildStaticNonFinalFieldInitializations(
+      OutputUnit outputUnit) {
+    jsAst.Statement buildInitialization(Element element,
+                                       jsAst.Expression initialValue) {
+      // Note: `namer.currentIsolate` refers to the isolate properties here.
+      return js.statement('${namer.currentIsolate}.# = #',
+                          [namer.globalPropertyName(element), initialValue]);
     }
 
     bool inMainUnit = (outputUnit == compiler.deferredLoadTask.mainOutputUnit);
     JavaScriptConstantCompiler handler = backend.constants;
+    List<jsAst.Statement> parts = <jsAst.Statement>[];
 
     Iterable<Element> fields = task.outputStaticNonFinalFieldLists[outputUnit];
     // If the outputUnit does not contain any static non-final fields, then
@@ -547,7 +552,7 @@
       for (Element element in fields) {
         compiler.withCurrentElement(element, () {
           ConstantValue constant = handler.getInitialValueFor(element).value;
-          emitInitialization(element, constantReference(constant));
+          parts.add(buildInitialization(element, constantReference(constant)));
         });
       }
     }
@@ -560,21 +565,23 @@
         if (fieldsOutputUnit == outputUnit) return;  // Skip the main unit.
         for (Element element in fields) {
           compiler.withCurrentElement(element, () {
-            emitInitialization(element, jsAst.number(0));
+            parts.add(buildInitialization(element, jsAst.number(0)));
           });
         }
       });
     }
+
+    return new jsAst.Block(parts);
   }
 
-  void emitLazilyInitializedStaticFields(CodeOutput output) {
+  jsAst.Statement buildLazilyInitializedStaticFields() {
     JavaScriptConstantCompiler handler = backend.constants;
     List<VariableElement> lazyFields =
         handler.getLazilyInitializedFieldsForEmission();
-    if (!lazyFields.isEmpty) {
+    if (lazyFields.isNotEmpty) {
       needsLazyInitializer = true;
       List<jsAst.Expression> laziesInfo = buildLaziesInfo(lazyFields);
-      jsAst.Statement code = js.statement('''
+      return js.statement('''
       (function(lazies) {
         if (#notInMinifiedMode) {
           var descriptorLength = 4;
@@ -604,10 +611,8 @@
       ''', {'notInMinifiedMode': !compiler.enableMinification,
             'laziesInfo': new jsAst.ArrayInitializer(laziesInfo),
             'lazy': js(lazyInitializerName)});
-
-      output.addBuffer(
-          jsAst.prettyPrint(code, compiler, monitor: compiler.dumpInfoTask));
-      output.add("$N");
+    } else {
+      return js.comment("No lazy statics.");
     }
   }
 
@@ -673,7 +678,8 @@
     }
   }
 
-  void emitMetadata(Program program, CodeOutput output, OutputUnit outputUnit) {
+  jsAst.Statement buildMetadata(Program program, OutputUnit outputUnit) {
+    List<jsAst.Statement> parts = <jsAst.Statement>[];
 
     jsAst.Expression constructList(List<jsAst.Expression> list) {
       return new jsAst.ArrayInitializer(list == null ? [] : list);
@@ -687,34 +693,24 @@
       jsAst.Expression typesAccess =
           generateEmbeddedGlobalAccess(embeddedNames.TYPES);
 
-      output.addBuffer(
-          jsAst.prettyPrint(new jsAst.Block([
-              js.statement('# = #;', [metadataAccess,
-                                      constructList(program.metadata)]),
-              js.statement('# = #;', [typesAccess, constructList(types)])]),
-              compiler, monitor: compiler.dumpInfoTask));
-      output.add(n);
+      parts..add(js.statement('# = #;', [metadataAccess,
+                                         constructList(program.metadata)]))
+           ..add(js.statement('# = #;', [typesAccess, constructList(types)]));
     } else if (types != null) {
-      output.addBuffer(
-          jsAst.prettyPrint(
-              js.statement('var ${namer.deferredTypesName} = #;',
-                           constructList(types)),
-              compiler, monitor: compiler.dumpInfoTask));
-      if (compiler.enableMinification) {
-        output.add('\n');
-      }
+      parts.add(js.statement('var ${namer.deferredTypesName} = #;',
+                             constructList(types)));
     }
+    return new jsAst.Block(parts);
   }
 
-  void emitCompileTimeConstants(CodeOutput output,
-                                List<Constant> constants,
-                                {bool isMainFragment}) {
+  jsAst.Statement buildCompileTimeConstants(List<Constant> constants,
+                                           {bool isMainFragment}) {
     assert(isMainFragment != null);
 
-    if (constants.isEmpty) return;
-    CodeOutput constantOutput = output;
+    if (constants.isEmpty) return js.comment("No constants in program.");
+    List<jsAst.Statement> parts = <jsAst.Statement>[];
     if (compiler.hasIncrementalSupport && isMainFragment) {
-      constantOutput = cachedEmittedConstantsBuffer;
+      parts = cachedEmittedConstantsAst;
     }
     for (Constant constant in constants) {
       ConstantValue constantValue = constant.value;
@@ -722,21 +718,17 @@
         if (cachedEmittedConstants.contains(constantValue)) continue;
         cachedEmittedConstants.add(constantValue);
       }
-      jsAst.Expression init = buildConstantInitializer(constantValue);
-      constantOutput.addBuffer(
-          jsAst.prettyPrint(init, compiler, monitor: compiler.dumpInfoTask));
-      constantOutput.add('$N');
+      parts.add(buildConstantInitializer(constantValue));
     }
-    if (compiler.hasIncrementalSupport && isMainFragment) {
-      output.addBuffer(constantOutput);
-    }
+
+    return new jsAst.Block(parts);
   }
 
-  jsAst.Expression buildConstantInitializer(ConstantValue constant) {
+  jsAst.Statement buildConstantInitializer(ConstantValue constant) {
     String name = namer.constantName(constant);
-    return js('#.# = #',
-              [namer.globalObjectForConstant(constant), name,
-               constantInitializerExpression(constant)]);
+    return js.statement('#.# = #',
+                        [namer.globalObjectForConstant(constant), name,
+                         constantInitializerExpression(constant)]);
   }
 
   jsAst.Template get makeConstantListTemplate {
@@ -745,59 +737,53 @@
         '${namer.isolateName}.$makeConstListProperty(#)');
   }
 
-  void emitMakeConstantList(CodeOutput output) {
-    output.addBuffer(
-        jsAst.prettyPrint(
-            // Functions are stored in the hidden class and not as properties in
-            // the object. We never actually look at the value, but only want
-            // to know if the property exists.
-            js.statement(r'''#.# = function(list) {
-                                     list.immutable$list = Array;
-                                     list.fixed$length = Array;
-                                     return list;
-                                   }''',
-                         [namer.isolateName, makeConstListProperty]),
-            compiler, monitor: compiler.dumpInfoTask));
-    output.add(N);
+  jsAst.Statement buildMakeConstantList() {
+    if (task.outputContainsConstantList) {
+      return js.statement(r'''
+          // Functions are stored in the hidden class and not as properties in
+          // the object. We never actually look at the value, but only want
+          // to know if the property exists.
+          #.# = function (list) {
+            list.immutable$list = Array;
+            list.fixed$length = Array;
+            return list;
+          }''',
+          [namer.isolateName, makeConstListProperty]);
+    } else {
+      return js.comment("Output contains no constant list.");
+    }
   }
 
-  void emitFunctionThatReturnsNull(CodeOutput output) {
-    output.addBuffer(
-        jsAst.prettyPrint(
-            js.statement('#.# = function() {}',
-                         [backend.namer.currentIsolate,
-                          backend.rti.getFunctionThatReturnsNullName]),
-            compiler, monitor: compiler.dumpInfoTask));
-    output.add(N);
+  jsAst.Statement buildFunctionThatReturnsNull() {
+    return js.statement('# = function() {}',
+                        [backend.rti.getFunctionThatReturnsNullName]);
   }
 
   jsAst.Expression generateFunctionThatReturnsNull() {
-    return js("#.#", [backend.namer.currentIsolate,
-                      backend.rti.getFunctionThatReturnsNullName]);
+    return js("#", [backend.rti.getFunctionThatReturnsNullName]);
   }
 
-  emitMain(CodeOutput output, jsAst.Statement invokeMain) {
-    if (compiler.isMockCompilation) return;
+  buildMain(jsAst.Statement invokeMain) {
+    if (compiler.isMockCompilation) return js.comment("Mock compilation");
+
+    List<jsAst.Statement> parts = <jsAst.Statement>[];
 
     if (NativeGenerator.needsIsolateAffinityTagInitialization(backend)) {
-      jsAst.Statement nativeBoilerPlate =
+      parts.add(
           NativeGenerator.generateIsolateAffinityTagInitialization(
               backend,
               generateEmbeddedGlobalAccess,
-              js("convertToFastObject", []));
-      output.addBuffer(jsAst.prettyPrint(
-          nativeBoilerPlate, compiler, monitor: compiler.dumpInfoTask));
+              js("convertToFastObject", [])));
     }
 
-    output.add(';');
-    addComment('BEGIN invoke [main].', output);
-    output.addBuffer(jsAst.prettyPrint(invokeMain,
-                     compiler, monitor: compiler.dumpInfoTask));
-    output.add(N);
-    addComment('END invoke [main].', output);
+    parts..add(js.comment('BEGIN invoke [main].'))
+         ..add(invokeMain)
+         ..add(js.comment('END invoke [main].'));
+
+    return new jsAst.Block(parts);
   }
 
-  void emitInitFunction(CodeOutput output) {
+  jsAst.Statement buildInitFunction() {
     jsAst.Expression allClassesAccess =
         generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
     jsAst.Expression getTypeFromNameAccess =
@@ -813,9 +799,9 @@
     jsAst.Expression laziesAccess =
         generateEmbeddedGlobalAccess(embeddedNames.LAZIES);
 
-    jsAst.FunctionDeclaration decl = js.statement('''
+    return js.statement('''
       function init() {
-        $isolateProperties = Object.create(null);
+        $isolatePropertiesName = Object.create(null);
         #allClasses = Object.create(null);
         #getTypeFromName = function(name) {return #allClasses[name];};
         #interceptorsByTag = Object.create(null);
@@ -834,7 +820,7 @@
             // 'prototype' will be undefined except if we are doing an update
             // during incremental compilation. In this case we put the lazy
             // field directly on the isolate instead of the isolateProperties.
-            prototype = prototype || $isolateProperties;
+            prototype = prototype || $isolatePropertiesName;
             var sentinelUndefined = {};
             var sentinelInProgress = {};
             prototype[fieldName] = sentinelUndefined;
@@ -933,15 +919,9 @@
             'makeConstListProperty': makeConstListProperty,
             'hasIncrementalSupport': compiler.hasIncrementalSupport,
             'lazyInitializerProperty': lazyInitializerProperty,});
-
-    output.addBuffer(
-        jsAst.prettyPrint(decl, compiler, monitor: compiler.dumpInfoTask));
-    if (compiler.enableMinification) {
-      output.add('\n');
-    }
   }
 
-  void emitConvertToFastObjectFunction(CodeOutput output) {
+  jsAst.Statement buildConvertToFastObjectFunction() {
     List<jsAst.Statement> debugCode = <jsAst.Statement>[];
     if (DEBUG_FAST_OBJECTS) {
       debugCode.add(js.statement(r'''
@@ -957,7 +937,7 @@
         }'''));
     }
 
-    jsAst.Statement convertToFastObject = js.statement(r'''
+    return js.statement(r'''
       function convertToFastObject(properties) {
         // Create an instance that uses 'properties' as prototype. This should
         // make 'properties' a fast object.
@@ -967,13 +947,10 @@
         #;
         return properties;
       }''', [debugCode]);
-
-    output.addBuffer(jsAst.prettyPrint(convertToFastObject, compiler));
-    output.add(N);
   }
 
-  void emitConvertToSlowObjectFunction(CodeOutput output) {
-    jsAst.Statement convertToSlowObject = js.statement(r'''
+  jsAst.Statement buildConvertToSlowObjectFunction() {
+    return js.statement(r'''
     function convertToSlowObject(properties) {
       // Add and remove a property to make the object transition into hashmap
       // mode.
@@ -981,12 +958,9 @@
       delete properties.__MAGIC_SLOW_PROPERTY;
       return properties;
     }''');
-
-    output.addBuffer(jsAst.prettyPrint(convertToSlowObject, compiler));
-    output.add(N);
   }
 
-  void emitSupportsDirectProtoAccess(CodeOutput output) {
+  jsAst.Statement buildSupportsDirectProtoAccess() {
     jsAst.Statement supportsDirectProtoAccess;
 
     if (compiler.hasIncrementalSupport) {
@@ -1005,8 +979,7 @@
       ''');
     }
 
-    output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler));
-    output.add(N);
+    return supportsDirectProtoAccess;
   }
 
   jsAst.Expression generateLibraryDescriptor(LibraryElement library,
@@ -1046,7 +1019,7 @@
     parts..add(js.string(libraryName))
          ..add(js.string(uri.toString()))
          ..add(metadata == null ? new jsAst.ArrayHole() : metadata)
-         ..add(js.name(namer.globalObjectFor(library)))
+         ..add(js('#', namer.globalObjectFor(library)))
          ..add(initializer);
     if (library == compiler.mainApp) {
       parts.add(js.number(1));
@@ -1073,7 +1046,7 @@
           #constructorName.#typeNameProperty = #constructorNameString;
           if (!"name" in #constructorName)
               #constructorName.name = #constructorNameString;
-          $desc = $collectedClasses.#constructorName[1];
+          $desc = $collectedClasses$.#constructorName[1];
           #constructorName.prototype = $desc;
           ''' /* next string is not a raw string */ '''
           if (#hasIsolateSupport) {
@@ -1132,7 +1105,95 @@
     }
   }
 
-  void emitMangledNames(CodeOutput output) {
+  jsAst.Statement buildGlobalObjectSetup(bool isProgramSplit) {
+    List<jsAst.Statement> parts = <jsAst.Statement>[];
+
+    parts.add(js.comment("""
+      // The global objects start as so-called "slow objects". For V8, this
+      // means that it won't try to make map transitions as we add properties
+      // to these objects. Later on, we attempt to turn these objects into
+      // fast objects by calling "convertToFastObject" (see
+      // [emitConvertToFastObjectFunction]).
+      """));
+
+    for (String globalObject in Namer.reservedGlobalObjectNames) {
+      if (isProgramSplit) {
+        String template =
+            "var #globalObject = #globalsHolder.#globalObject = map();";
+        parts.add(js.statement(template, {"globalObject": globalObject,
+                                          "globalsHolder": globalsHolder}));
+      } else {
+        parts.add(js.statement("var #globalObject = map();",
+                               {"globalObject": globalObject}));
+      }
+
+    }
+
+    return new jsAst.Block(parts);
+  }
+
+  jsAst.Statement buildConvertGlobalObjectToFastObjects() {
+    List<jsAst.Statement> parts = <jsAst.Statement>[];
+
+    for (String globalObject in Namer.reservedGlobalObjectNames) {
+      parts.add(js.statement(
+          '#globalObject = convertToFastObject(#globalObject);',
+          {"globalObject": globalObject}));
+    }
+
+    return new jsAst.Block(parts);
+  }
+
+  jsAst.Statement buildDebugFastObjectCode() {
+    List<jsAst.Statement> parts = <jsAst.Statement>[];
+
+    if (DEBUG_FAST_OBJECTS) {
+      parts.add(js.statement(r'''
+          // The following only works on V8 when run with option
+          // "--allow-natives-syntax".  We use'new Function' because the
+          // miniparser does not understand V8 native syntax.
+          if (typeof print === "function") {
+            var HasFastProperties =
+              new Function("a", "return %HasFastProperties(a)");
+            print("Size of global helper object: "
+                   + String(Object.getOwnPropertyNames(H).length)
+                   + ", fast properties " + HasFastProperties(H));
+            print("Size of global platform object: "
+                   + String(Object.getOwnPropertyNames(P).length)
+                   + ", fast properties " + HasFastProperties(P));
+            print("Size of global dart:html object: "
+                   + String(Object.getOwnPropertyNames(W).length)
+                   + ", fast properties " + HasFastProperties(W));
+            print("Size of isolate properties object: "
+                   + String(Object.getOwnPropertyNames($).length)
+                   + ", fast properties " + HasFastProperties($));
+            print("Size of constant object: "
+                   + String(Object.getOwnPropertyNames(C).length)
+                   + ", fast properties " + HasFastProperties(C));
+            var names = Object.getOwnPropertyNames($);
+            for (var i = 0; i < names.length; i++) {
+              print("$." + names[i]);
+            }
+          }
+       '''));
+
+      for (String object in Namer.userGlobalObjects) {
+        parts.add(js.statement('''
+          if (typeof print === "function") {
+            print("Size of " + #objectString + ": "
+                  + String(Object.getOwnPropertyNames(#object).length)
+                  + ", fast properties " + HasFastProperties(#object));
+          }
+        ''', {"object": object, "objectString": js.string(object)}));
+      }
+    }
+
+    return new jsAst.Block(parts);
+  }
+
+  jsAst.Statement buildMangledNames() {
+    List<jsAst.Statement> parts = <jsAst.Statement>[];
+
     if (!mangledFieldNames.isEmpty) {
       var keys = mangledFieldNames.keys.toList();
       keys.sort();
@@ -1145,15 +1206,9 @@
       jsAst.Expression mangledNamesAccess =
           generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
       var map = new jsAst.ObjectInitializer(properties);
-      output.addBuffer(
-          jsAst.prettyPrint(
-              js.statement('# = #', [mangledNamesAccess, map]),
-              compiler,
-              monitor: compiler.dumpInfoTask));
-      if (compiler.enableMinification) {
-        output.add(';');
-      }
+      parts.add(js.statement('# = #', [mangledNamesAccess, map]));
     }
+
     if (!mangledGlobalFieldNames.isEmpty) {
       var keys = mangledGlobalFieldNames.keys.toList();
       keys.sort();
@@ -1165,15 +1220,10 @@
       jsAst.Expression mangledGlobalNamesAccess =
           generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
       var map = new jsAst.ObjectInitializer(properties);
-      output.addBuffer(
-          jsAst.prettyPrint(
-              js.statement('# = #', [mangledGlobalNamesAccess, map]),
-              compiler,
-              monitor: compiler.dumpInfoTask));
-      if (compiler.enableMinification) {
-        output.add(';');
-      }
+      parts.add(js.statement('# = #', [mangledGlobalNamesAccess, map]));
     }
+
+    return new jsAst.Block(parts);
   }
 
   void checkEverythingEmitted(Iterable<Element> elements) {
@@ -1235,97 +1285,32 @@
 
     bool isProgramSplit = program.isSplit;
 
-    mainOutput.add(buildGeneratedBy());
-    addComment(HOOKS_API_USAGE, mainOutput);
+    List<jsAst.Statement> statements = <jsAst.Statement>[];
+
+    statements..add(buildGeneratedBy())
+              ..add(js.comment(HOOKS_API_USAGE));
 
     if (isProgramSplit) {
       /// For deferred loading we communicate the initializers via this global
       /// variable. The deferred hunks will add their initialization to this.
       /// The semicolon is important in minified mode, without it the
       /// following parenthesis looks like a call to the object literal.
-      mainOutput.add(
-          'self.${deferredInitializers} = self.${deferredInitializers} || '
-          'Object.create(null);$n');
+      statements.add(
+          js.statement('self.#deferredInitializers = '
+                       'self.#deferredInitializers || Object.create(null);',
+                       {'deferredInitializers': deferredInitializers}));
     }
 
-    // Using a named function here produces easier to read stack traces in
-    // Chrome/V8.
-    mainOutput.add('(function(${namer.currentIsolate})$_{\n');
-    emitSupportsDirectProtoAccess(mainOutput);
-    if (compiler.hasIncrementalSupport) {
-      mainOutput.addBuffer(jsAst.prettyPrint(js.statement(
-          """
-{
-  #helper = #helper || Object.create(null);
-  #helper.patch = function(a) { eval(a)};
-  #helper.schemaChange = #schemaChange;
-  #helper.addMethod = #addMethod;
-  #helper.extractStubs = function(array, name, isStatic, originalDescriptor) {
-    var descriptor = Object.create(null);
-    this.addStubs(descriptor, array, name, isStatic, []);
-    return descriptor;
-  };
-}""",
-          { 'helper': js('this.#', [namer.incrementalHelperName]),
-            'schemaChange': buildSchemaChangeFunction(),
-            'addMethod': buildIncrementalAddMethod() }), compiler));
-    }
-    if (isProgramSplit) {
-      /// We collect all the global state, so it can be passed to the
-      /// initializer of deferred files.
-      mainOutput.add('var ${globalsHolder}$_=${_}Object.create(null)$N');
-    }
-
-    jsAst.Statement mapFunction = js.statement('''
-// [map] returns an object that V8 shouldn't try to optimize with a hidden
-// class. This prevents a potential performance problem where V8 tries to build
-// a hidden class for an object used as a hashMap.
-// It requires fewer characters to declare a variable as a parameter than
-// with `var`.
-  function map(x) {
-    x = Object.create(null);
-    x.x = 0;
-    delete x.x;
-    return x;
-  }
-''');
-    mainOutput.addBuffer(jsAst.prettyPrint(mapFunction, compiler));
-    for (String globalObject in Namer.reservedGlobalObjectNames) {
-      // The global objects start as so-called "slow objects". For V8, this
-      // means that it won't try to make map transitions as we add properties
-      // to these objects. Later on, we attempt to turn these objects into
-      // fast objects by calling "convertToFastObject" (see
-      // [emitConvertToFastObjectFunction]).
-      mainOutput.add('var ${globalObject}$_=${_}');
-      if(isProgramSplit) {
-        mainOutput.add('${globalsHolder}.$globalObject$_=${_}');
-      }
-      mainOutput.add('map()$N');
-    }
-
-    mainOutput.add('function ${namer.isolateName}()$_{}\n');
-    if (isProgramSplit) {
-      mainOutput.add(
-          '${globalsHolder}.${namer.isolateName}$_=$_${namer.isolateName}$N'
-          '${globalsHolder}.$initName$_=${_}$initName$N'
-          '${globalsHolder}.$setupProgramName$_=$_'
-            '$setupProgramName$N');
-    }
-    mainOutput.add('init()$N$n');
-    mainOutput.add('$isolateProperties$_=$_$isolatePropertiesName$N');
-
-    emitFunctionThatReturnsNull(mainOutput);
-
-    Iterable<LibraryElement> libraries =
-        task.outputLibraryLists[mainOutputUnit];
-    if (libraries == null) libraries = [];
-    emitMangledNames(mainOutput);
-
+    // Collect the AST for the decriptors
     Map<Element, ClassBuilder> descriptors = elementDescriptors[mainFragment];
     if (descriptors == null) descriptors = const {};
 
     checkEverythingEmitted(descriptors.keys);
 
+    Iterable<LibraryElement> libraries =
+        task.outputLibraryLists[mainOutputUnit];
+    if (libraries == null) libraries = <LibraryElement>[];
+
     List<jsAst.Expression> parts = <jsAst.Expression>[];
     for (LibraryElement library in Elements.sortedByPosition(libraries)) {
       parts.add(generateLibraryDescriptor(library, mainFragment));
@@ -1334,8 +1319,8 @@
 
     if (descriptors.isNotEmpty) {
       List<Element> remainingLibraries = descriptors.keys
-          .where((Element e) => e is LibraryElement)
-          .toList();
+      .where((Element e) => e is LibraryElement)
+      .toList();
 
       // The remaining descriptors are only accessible through reflection.
       // The program builder does not collect libraries that only
@@ -1350,127 +1335,166 @@
     }
     jsAst.ArrayInitializer descriptorsAst = new jsAst.ArrayInitializer(parts);
 
-    bool needsNativeSupport = program.needsNativeSupport;
-    mainOutput.addBuffer(
-        jsAst.prettyPrint(
-            buildSetupProgram(program, compiler, backend, namer, this),
-            compiler));
+    // Using a named function here produces easier to read stack traces in
+    // Chrome/V8.
+    statements.add(js.statement("""
+    (function() {
+       // No renaming in the top-level function to save the locals for the
+       // nested context where they will be used more. We have to put the
+       // comment into a hole as the parser strips out comments right away.
+       #disableVariableRenaming;
+       #supportsDirectProtoAccess;
 
-    // The argument to reflectionDataParser is assigned to a temporary 'dart'
-    // so that 'dart.' will appear as the prefix to dart methods in stack
-    // traces and profile entries.
-    mainOutput..add('var dart =')
-              ..addBuffer(jsAst.prettyPrint(descriptorsAst, compiler,
-                                            monitor: compiler.dumpInfoTask))
-              ..add('$N');
-    if (compiler.useContentSecurityPolicy) {
-      jsAst.Statement precompiledFunctionAst =
-          buildCspPrecompiledFunctionFor(mainOutputUnit);
-      mainOutput.addBuffer(
-          jsAst.prettyPrint(
-              precompiledFunctionAst,
-              compiler,
-              monitor: compiler.dumpInfoTask,
-              allowVariableMinification: false));
-      mainOutput.add(N);
-    }
+       if (#hasIncrementalSupport) {
+         #helper = #helper || Object.create(null);
+         #helper.patch = function(a) { eval(a)};
+         #helper.schemaChange = #schemaChange;
+         #helper.addMethod = #addMethod;
+         #helper.extractStubs =
+           function(array, name, isStatic, originalDescriptor) {
+             var descriptor = Object.create(null);
+             this.addStubs(descriptor, array, name, isStatic, []);
+             return descriptor;
+            };
+       }
 
-    mainOutput.add('$setupProgramName(dart, 0)$N');
+       if (#isProgramSplit) {
+         /// We collect all the global state, so it can be passed to the
+         /// initializer of deferred files.
+         var #globalsHolder = Object.create(null)
+       }
 
-    interceptorEmitter.emitGetInterceptorMethods(mainOutput);
-    interceptorEmitter.emitOneShotInterceptors(mainOutput);
+       // [map] returns an object that V8 shouldn't try to optimize with a
+       // hidden class. This prevents a potential performance problem where V8
+       // tries to build a hidden class for an object used as a hashMap.
+       // It requires fewer characters to declare a variable as a parameter than
+       // with `var`.
+       function map(x) {
+         x = Object.create(null);
+         x.x = 0;
+         delete x.x;
+         return x;
+       }
 
-    if (task.outputContainsConstantList) {
-      emitMakeConstantList(mainOutput);
-    }
+       #globalObjectSetup;
 
-    // Constants in checked mode call into RTI code to set type information
-    // which may need getInterceptor (and one-shot interceptor) methods, so
-    // we have to make sure that [emitGetInterceptorMethods] and
-    // [emitOneShotInterceptors] have been called.
-    emitCompileTimeConstants(
-        mainOutput, mainFragment.constants, isMainFragment: true);
+       function #isolateName() {}
 
-    emitDeferredBoilerPlate(mainOutput, deferredLoadHashes);
+       if (#isProgramSplit) {
+         #globalsHolder.#isolateName = #isolateName;
+         #globalsHolder.#initName = #initName;
+         #globalsHolder.#setupProgramName = #setupProgramName;
+       }
+
+       init();
+
+       #mangledNames;
+
+       #cspPrecompiledFunctions;
+
+       #setupProgram;
+
+       #functionThatReturnsNull;
+
+       // The argument to reflectionDataParser is assigned to a temporary 'dart'
+       // so that 'dart.' will appear as the prefix to dart methods in stack
+       // traces and profile entries.
+       var dart = #descriptors;
+
+       #setupProgramName(dart, 0);
+
+       #getInterceptorMethods;
+       #oneShotInterceptors;
+
+       #makeConstantList;
+
+       // We abuse the short name used for the isolate here to store
+       // the isolate properties. This is safe as long as the real isolate
+       // object does not exist yet.
+       var ${namer.currentIsolate} = #isolatePropertiesName;
+
+       // Constants in checked mode call into RTI code to set type information
+       // which may need getInterceptor (and one-shot interceptor) methods, so
+       // we have to make sure that [emitGetInterceptorMethods] and
+       // [emitOneShotInterceptors] have been called.
+       #compileTimeConstants;
+
+       // Static field initializations require the classes and compile-time
+       // constants to be set up.
+       #staticNonFinalInitializers;
+
+       ${namer.currentIsolate} = null;
+
+       #deferredBoilerPlate;
+
+       #typeToInterceptorMap;
+
+       #lazyStaticFields;
+
+       #isolateName = $finishIsolateConstructorName(#isolateName);
+
+       ${namer.currentIsolate} = new #isolateName();
+
+       #metadata;
+
+       #convertToFastObject;
+       #convertToSlowObject;
+
+       #convertGlobalObjectsToFastObjects;
+       #debugFastObjects;
+
+       #init;
+
+       #main;
+    })();
+    """, {
+      "disableVariableRenaming": js.comment("/* ::norenaming:: */"),
+      "hasIncrementalSupport": compiler.hasIncrementalSupport,
+      "helper": js('this.#', [namer.incrementalHelperName]),
+      "schemaChange": buildSchemaChangeFunction(),
+      "addMethod": buildIncrementalAddMethod(),
+      "isProgramSplit": isProgramSplit,
+      "supportsDirectProtoAccess": buildSupportsDirectProtoAccess(),
+      "globalsHolder": globalsHolder,
+      "globalObjectSetup": buildGlobalObjectSetup(isProgramSplit),
+      "isolateName": namer.isolateName,
+      "isolatePropertiesName": js(isolatePropertiesName),
+      "initName": initName,
+      "functionThatReturnsNull": buildFunctionThatReturnsNull(),
+      "mangledNames": buildMangledNames(),
+      "setupProgram": buildSetupProgram(program, compiler, backend, namer, this),
+      "setupProgramName": setupProgramName,
+      "descriptors": descriptorsAst,
+      "cspPrecompiledFunctions": buildCspPrecompiledFunctionFor(mainOutputUnit),
+      "getInterceptorMethods": interceptorEmitter.buildGetInterceptorMethods(),
+      "oneShotInterceptors": interceptorEmitter.buildOneShotInterceptors(),
+      "makeConstantList": buildMakeConstantList(),
+      "compileTimeConstants":  buildCompileTimeConstants(mainFragment.constants,
+                                                         isMainFragment: true),
+      "deferredBoilerPlate": buildDeferredBoilerPlate(deferredLoadHashes),
+      "staticNonFinalInitializers": buildStaticNonFinalFieldInitializations(
+          mainOutputUnit),
+      "typeToInterceptorMap":
+          interceptorEmitter.buildTypeToInterceptorMap(program),
+      "lazyStaticFields": buildLazilyInitializedStaticFields(),
+      "metadata": buildMetadata(program, mainOutputUnit),
+      "convertToFastObject": buildConvertToFastObjectFunction(),
+      "convertToSlowObject": buildConvertToSlowObjectFunction(),
+      "convertGlobalObjectsToFastObjects":
+          buildConvertGlobalObjectToFastObjects(),
+      "debugFastObjects": buildDebugFastObjectCode(),
+      "init": buildInitFunction(),
+      "main": buildMain(mainFragment.invokeMain)
+    }));
+
+    mainOutput.addBuffer(jsAst.prettyPrint(new jsAst.Program(statements),
+                                           compiler,
+                                           monitor: compiler.dumpInfoTask));
 
     if (compiler.deferredMapUri != null) {
       outputDeferredMap();
     }
 
-    // Static field initializations require the classes and compile-time
-    // constants to be set up.
-    emitStaticNonFinalFieldInitializations(mainOutput, mainOutputUnit);
-    interceptorEmitter.emitTypeToInterceptorMap(program, mainOutput);
-    if (compiler.enableMinification) {
-      mainOutput.add(';');
-    }
-    emitLazilyInitializedStaticFields(mainOutput);
-
-    mainOutput.add('\n');
-
-    emitMetadata(program, mainOutput, mainOutputUnit);
-
-    isolateProperties = isolatePropertiesName;
-    // The following code should not use the short-hand for the
-    // initialStatics.
-    mainOutput.add('${namer.currentIsolate}$_=${_}null$N');
-
-    emitFinishIsolateConstructorInvocation(mainOutput);
-    mainOutput.add(
-        '${namer.currentIsolate}$_=${_}new ${namer.isolateName}()$N');
-
-    emitConvertToFastObjectFunction(mainOutput);
-    emitConvertToSlowObjectFunction(mainOutput);
-
-    for (String globalObject in Namer.reservedGlobalObjectNames) {
-      mainOutput.add('$globalObject = convertToFastObject($globalObject)$N');
-    }
-    if (DEBUG_FAST_OBJECTS) {
-      mainOutput.add(r'''
-          // The following only works on V8 when run with option
-          // "--allow-natives-syntax".  We use'new Function' because the
-          // miniparser does not understand V8 native syntax.
-          if (typeof print === "function") {
-            var HasFastProperties =
-              new Function("a", "return %HasFastProperties(a)");
-            print("Size of global helper object: "
-                   + String(Object.getOwnPropertyNames(H).length)
-                   + ", fast properties " + HasFastProperties(H));
-            print("Size of global platform object: "
-                   + String(Object.getOwnPropertyNames(P).length)
-                   + ", fast properties " + HasFastProperties(P));
-            print("Size of global dart:html object: "
-                   + String(Object.getOwnPropertyNames(W).length)
-                   + ", fast properties " + HasFastProperties(W));
-            print("Size of isolate properties object: "
-                   + String(Object.getOwnPropertyNames($).length)
-                   + ", fast properties " + HasFastProperties($));
-            print("Size of constant object: "
-                   + String(Object.getOwnPropertyNames(C).length)
-                   + ", fast properties " + HasFastProperties(C));
-            var names = Object.getOwnPropertyNames($);
-            for (var i = 0; i < names.length; i++) {
-              print("$." + names[i]);
-            }
-          }
-''');
-      for (String object in Namer.userGlobalObjects) {
-      mainOutput.add('''
-        if (typeof print === "function") {
-           print("Size of $object: "
-                 + String(Object.getOwnPropertyNames($object).length)
-                 + ", fast properties " + HasFastProperties($object));
-}
-''');
-      }
-    }
-
-    emitInitFunction(mainOutput);
-    emitMain(mainOutput, mainFragment.invokeMain);
-
-    mainOutput.add('})()\n');
-
-
     if (generateSourceMap) {
       mainOutput.add(
           generateSourceMapTag(compiler.sourceMapUri, compiler.outputUri));
@@ -1487,6 +1511,7 @@
   /// Used by incremental compilation to patch up the prototype of
   /// [oldConstructor] for use as prototype of [newConstructor].
   jsAst.Fun buildSchemaChangeFunction() {
+    if (!compiler.hasIncrementalSupport) return null;
     return js('''
 function(newConstructor, oldConstructor, superclass) {
   // Invariant: newConstructor.prototype has no interesting properties besides
@@ -1519,6 +1544,7 @@
   /// top-level). [globalFunctionsAccess] is a reference to
   /// [embeddedNames.GLOBAL_FUNCTIONS].
   jsAst.Fun buildIncrementalAddMethod() {
+    if (!compiler.hasIncrementalSupport) return null;
     return js(r"""
 function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
   var arrayOrFunction = originalDescriptor[name];
@@ -1599,13 +1625,8 @@
 }""");
   }
 
-  /// Returns a map from OutputUnit to a hash of its content. The hash uniquely
-  /// identifies the code of the output-unit. It does not include
-  /// boilerplate JS code, like the sourcemap directives or the hash
-  /// itself.
-  Map<OutputUnit, String> emitDeferredOutputUnits(Program program) {
-    if (!program.isSplit) return const {};
-
+  Map<OutputUnit, jsAst.Expression> buildDescriptorsForOutputUnits(
+      Program program) {
     Map<OutputUnit, jsAst.Expression> outputs =
         new Map<OutputUnit, jsAst.Expression>();
 
@@ -1616,7 +1637,7 @@
 
       if (descriptors != null && descriptors.isNotEmpty) {
         Iterable<LibraryElement> libraries =
-            task.outputLibraryLists[outputUnit];
+        task.outputLibraryLists[outputUnit];
         if (libraries == null) libraries = [];
 
         // TODO(johnniwinther): Avoid creating [CodeBuffer]s.
@@ -1630,7 +1651,7 @@
       }
     }
 
-    return emitDeferredCode(program, outputs);
+    return outputs;
   }
 
   int emitProgram(ProgramBuilder programBuilder) {
@@ -1639,8 +1660,9 @@
 
     assembleProgram(program);
 
-    // Shorten the code by using [namer.currentIsolate] as temporary.
-    isolateProperties = namer.currentIsolate;
+    // Construct the ASTs for all deferred output units.
+    Map<OutputUnit, jsAst.Program> deferredParts =
+        buildOutputAstForDeferredCode(program);
 
     // Emit deferred units first, so we have their hashes.
     // Map from OutputUnit to a hash of its content. The hash uniquely
@@ -1648,7 +1670,7 @@
     // boilerplate JS code, like the sourcemap directives or the hash
     // itself.
     Map<OutputUnit, String> deferredLoadHashes =
-        emitDeferredOutputUnits(program);
+        emitDeferredOutputUnits(deferredParts);
     emitMainOutputUnit(program, deferredLoadHashes);
 
     if (backend.requiresPreamble &&
@@ -1694,9 +1716,11 @@
   }
 
   /// Emits support-code for deferred loading into [output].
-  void emitDeferredBoilerPlate(CodeOutput output,
-                               Map<OutputUnit, String> deferredLoadHashes) {
-    jsAst.Statement functions = js.statement('''
+  jsAst.Statement buildDeferredBoilerPlate(
+      Map<OutputUnit, String> deferredLoadHashes) {
+    List<jsAst.Statement> parts = <jsAst.Statement>[];
+
+    parts.add(js.statement('''
         {
           // Function for checking if a hunk is loaded given its hash.
           #isHunkLoaded = function(hunkHash) {
@@ -1721,9 +1745,8 @@
               "initializeLoadedHunk": generateEmbeddedGlobalAccess(
                   embeddedNames.INITIALIZE_LOADED_HUNK),
               "deferredInitialized": generateEmbeddedGlobalAccess(
-                  embeddedNames.DEFERRED_INITIALIZED)});
-    output.addBuffer(jsAst.prettyPrint(functions,
-        compiler, monitor: compiler.dumpInfoTask));
+                  embeddedNames.DEFERRED_INITIALIZED)}));
+
     // Write a javascript mapping from Deferred import load ids (derrived
     // from the import prefix.) to a list of lists of uris of hunks to load,
     // and a corresponding mapping to a list of hashes used by
@@ -1757,31 +1780,99 @@
           new jsAst.ObjectInitializer(properties, isOneLiner: true);
 
       jsAst.Node globalName = generateEmbeddedGlobalAccess(name);
-      output.addBuffer(jsAst.prettyPrint(
-          js("# = #", [globalName, initializer]),
-          compiler, monitor: compiler.dumpInfoTask));
-      output.add('$N');
+      parts.add(js.statement("# = #", [globalName, initializer]));
     }
 
     emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris);
     emitMapping(embeddedNames.DEFERRED_LIBRARY_HASHES,
                 deferredLibraryHashes);
+
+    return new jsAst.Block(parts);
   }
 
-  /// Emits code for all output units except the main.
-  /// Returns a mapping from outputUnit to a hash of the corresponding hunk that
-  /// can be used for calling the initializer.
-  Map<OutputUnit, String> emitDeferredCode(
-      Program program,
-      Map<OutputUnit, jsAst.Expression> deferredAsts) {
+  Map <OutputUnit, jsAst.Program> buildOutputAstForDeferredCode(
+      Program program) {
+    if (!program.isSplit) return const <OutputUnit, jsAst.Program>{};
 
-    Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>();
+    Map<OutputUnit, jsAst.Program> result =
+        new Map<OutputUnit, jsAst.Program>();
+
+    Map<OutputUnit, jsAst.Expression> deferredAsts =
+        buildDescriptorsForOutputUnits(program);
 
     for (Fragment fragment in program.deferredFragments) {
       OutputUnit outputUnit = fragment.outputUnit;
-
       jsAst.Expression libraryDescriptor = deferredAsts[outputUnit];
+      List<jsAst.Statement> body = <jsAst.Statement>[];
 
+      // No renaming in the top-level function to save the locals for the
+      // nested context where they will be used more.
+      body.add(js.comment("/* ::norenaming:: "));
+
+      for (String globalObject in Namer.reservedGlobalObjectNames) {
+        body.add(js.statement('var #object = ${globalsHolder}.#object;',
+                              {'object': globalObject}));
+      }
+      body..add(js.statement('var init = ${globalsHolder}.init;'))
+          ..add(js.statement('var $setupProgramName = '
+                             '$globalsHolder.$setupProgramName;'))
+          ..add(js.statement('var ${namer.isolateName} = '
+                             '${globalsHolder}.${namer.isolateName};'));
+      String typesAccess =
+          generateEmbeddedGlobalAccessString(embeddedNames.TYPES);
+      if (libraryDescriptor != null) {
+        // The argument to reflectionDataParser is assigned to a temporary
+        // 'dart' so that 'dart.' will appear as the prefix to dart methods
+        // in stack traces and profile entries.
+        body.add(js.statement('var dart = #', libraryDescriptor));
+
+        if (compiler.useContentSecurityPolicy) {
+          body.add(buildCspPrecompiledFunctionFor(outputUnit));
+        }
+        body.add(
+            js.statement('$setupProgramName(dart, ${typesAccess}.length);'));
+      }
+
+      if (task.metadataCollector.types[outputUnit] != null) {
+        body..add(buildMetadata(program, outputUnit))
+            ..add(js.statement('${typesAccess}.push.apply(${typesAccess}, '
+                               '${namer.deferredTypesName});'));
+      }
+
+      // Set the currentIsolate variable to the current isolate (which is
+      // provided as second argument).
+      body.add(js.statement("${namer.currentIsolate} = arguments[1];"));
+
+      body.add(buildCompileTimeConstants(fragment.constants,
+                                         isMainFragment: false));
+      body.add(buildStaticNonFinalFieldInitializations(outputUnit));
+
+      List<jsAst.Statement> statements = <jsAst.Statement>[];
+
+      statements
+          ..add(buildGeneratedBy())
+          ..add(js.statement('${deferredInitializers}.current = '
+                             """function (${globalsHolder}) {
+                                  #
+                                }
+                             """, [body]));
+
+      result[outputUnit] = new jsAst.Program(statements);
+    }
+
+    return result;
+  }
+
+  /// Returns a map from OutputUnit to a hash of its content. The hash uniquely
+  /// identifies the code of the output-unit. It does not include
+  /// boilerplate JS code, like the sourcemap directives or the hash
+  /// itself.
+  Map<OutputUnit, String> emitDeferredOutputUnits(
+      Map<OutputUnit, jsAst.Program> outputAsts) {
+
+    Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>();
+
+    for (OutputUnit outputUnit in outputAsts.keys) {
       List<CodeOutputListener> outputListeners = <CodeOutputListener>[];
       Hasher hasher = new Hasher();
       outputListeners.add(hasher);
@@ -1800,84 +1891,19 @@
 
       outputBuffers[outputUnit] = output;
 
-      output
-          ..add(buildGeneratedBy())
-          ..add('${deferredInitializers}.current$_=$_'
-                   'function$_(${globalsHolder}) {$N');
-      for (String globalObject in Namer.reservedGlobalObjectNames) {
-        output
-            .add('var $globalObject$_=$_'
-                     '${globalsHolder}.$globalObject$N');
-      }
-      output
-          ..add('var init$_=$_${globalsHolder}.init$N')
-          ..add('var $setupProgramName$_=$_'
-                    '$globalsHolder.$setupProgramName$N')
-          ..add('var ${namer.isolateName}$_=$_'
-                    '${globalsHolder}.${namer.isolateName}$N');
-      String typesAccess =
-          generateEmbeddedGlobalAccessString(embeddedNames.TYPES);
-      if (libraryDescriptor != null) {
-        // TODO(ahe): This defines a lot of properties on the
-        // Isolate.prototype object.  We know this will turn it into a
-        // slow object in V8, so instead we should do something similar
-        // to Isolate.$finishIsolateConstructor.
-        output
-            ..add('var ${namer.currentIsolate}$_=$_$isolatePropertiesName$N')
-            // The argument to reflectionDataParser is assigned to a temporary
-            // 'dart' so that 'dart.' will appear as the prefix to dart methods
-            // in stack traces and profile entries.
-            ..add('var dart = $n ')
-            ..addBuffer(jsAst.prettyPrint(libraryDescriptor, compiler,
-                                          monitor: compiler.dumpInfoTask))
-            ..add('$N');
+      output.addBuffer(jsAst.prettyPrint(outputAsts[outputUnit],
+                                         compiler,
+                                         monitor: compiler.dumpInfoTask));
 
-        if (compiler.useContentSecurityPolicy) {
-          jsAst.Statement precompiledFunctionAst =
-              buildCspPrecompiledFunctionFor(outputUnit);
-
-          output.addBuffer(
-              jsAst.prettyPrint(
-                  precompiledFunctionAst, compiler,
-                  monitor: compiler.dumpInfoTask,
-                  allowVariableMinification: false));
-          output.add(N);
-        }
-        output.add('$setupProgramName(dart, ${typesAccess}.length)$N');
-      }
-
-      if (task.metadataCollector.types[outputUnit] != null) {
-        emitMetadata(program, output, outputUnit);
-        output.add('${typesAccess}.'
-                   'push.apply(${typesAccess},$_${namer.deferredTypesName})$N');
-      }
-
-      // Set the currentIsolate variable to the current isolate (which is
-      // provided as second argument).
-      // We need to do this, because we use the same variable for setting up
-      // the isolate-properties and for storing the current isolate. During
-      // the setup (the code above this lines) we must set the variable to
-      // the isolate-properties.
-      // After we have done the setup it must point to the current Isolate.
-      // Otherwise all methods/functions accessing isolate variables will
-      // access the wrong object.
-      output.add("${namer.currentIsolate}$_=${_}arguments[1]$N");
-
-      emitCompileTimeConstants(
-          output, fragment.constants, isMainFragment: false);
-      emitStaticNonFinalFieldInitializations(output, outputUnit);
-
-      output.add('}$N');
       // Make a unique hash of the code (before the sourcemaps are added)
       // This will be used to retrieve the initializing function from the global
       // variable.
       String hash = hasher.getHash();
 
-      output.add('${deferredInitializers}["$hash"]$_=$_'
+      output.add('$N${deferredInitializers}["$hash"]$_=$_'
                        '${deferredInitializers}.current$N');
 
       if (generateSourceMap) {
-
         Uri mapUri, partUri;
         Uri sourceMapUri = compiler.sourceMapUri;
         Uri outputUri = compiler.outputUri;
@@ -1911,10 +1937,12 @@
     return hunkHashes;
   }
 
-  String buildGeneratedBy() {
-    var suffix = '';
+  jsAst.Comment buildGeneratedBy() {
+    String suffix = '';
     if (compiler.hasBuildId) suffix = ' version: ${compiler.buildId}';
-    return '// Generated by dart2js, the Dart to JavaScript compiler$suffix.\n';
+    String msg = '// Generated by dart2js, the Dart to JavaScript '
+                 'compiler$suffix.';
+    return new jsAst.Comment(msg);
   }
 
   void outputSourceMap(CodeOutput output,
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/interceptor_emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/interceptor_emitter.dart
index 6db7c71..aa43580 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/interceptor_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/interceptor_emitter.dart
@@ -13,35 +13,40 @@
     }
   }
 
-  void emitGetInterceptorMethod(CodeOutput output,
-                                String key,
-                                Set<ClassElement> classes) {
+  jsAst.Expression buildGetInterceptorMethod(String key,
+                                             Set<ClassElement> classes) {
     InterceptorStubGenerator stubGenerator =
         new InterceptorStubGenerator(compiler, namer, backend);
     jsAst.Expression function =
         stubGenerator.generateGetInterceptorMethod(classes);
 
-    output.addBuffer(jsAst.prettyPrint(
-        js('${namer.globalObjectFor(backend.interceptorsLibrary)}.# = #',
-           [key, function]),
-        compiler));
-    output.add(N);
+    return function;
   }
 
   /**
    * Emit all versions of the [:getInterceptor:] method.
    */
-  void emitGetInterceptorMethods(CodeOutput output) {
-    emitter.addComment('getInterceptor methods', output);
+  jsAst.Statement buildGetInterceptorMethods() {
+    List<jsAst.Statement> parts = <jsAst.Statement>[];
+
+    parts.add(js.comment('getInterceptor methods'));
+
     Map<String, Set<ClassElement>> specializedGetInterceptors =
         backend.specializedGetInterceptors;
     for (String name in specializedGetInterceptors.keys.toList()..sort()) {
       Set<ClassElement> classes = specializedGetInterceptors[name];
-      emitGetInterceptorMethod(output, name, classes);
+      parts.add(
+          js.statement('#.# = #',
+                       [namer.globalObjectFor(backend.interceptorsLibrary),
+                        name,
+                        buildGetInterceptorMethod(name, classes)]));
     }
+
+    return new jsAst.Block(parts);
   }
 
-  void emitOneShotInterceptors(CodeOutput output) {
+  jsAst.Statement buildOneShotInterceptors() {
+    List<jsAst.Statement> parts = <jsAst.Statement>[];
     List<String> names = backend.oneShotInterceptors.keys.toList();
     names.sort();
 
@@ -51,12 +56,10 @@
     for (String name in names) {
       jsAst.Expression function =
           stubGenerator.generateOneShotInterceptor(name);
-      jsAst.Expression assignment =
-          js('${globalObject}.# = #', [name, function]);
-
-      output.addBuffer(jsAst.prettyPrint(assignment, compiler));
-      output.add(N);
+      parts.add(js.statement('${globalObject}.# = #', [name, function]));
     }
+
+    return new jsAst.Block(parts);
   }
 
   /**
@@ -87,15 +90,12 @@
    * `findInterceptorForType`.  See declaration of `typeToInterceptor` in
    * `interceptors.dart`.
    */
-  void emitTypeToInterceptorMap(Program program, CodeOutput output) {
+  jsAst.Statement buildTypeToInterceptorMap(Program program) {
     jsAst.Expression array = program.typeToInterceptorMap;
-    if (array == null) return;
+    if (array == null) return js.comment("Empty type-to-interceptor map.");
 
     jsAst.Expression typeToInterceptorMap = emitter
         .generateEmbeddedGlobalAccess(embeddedNames.TYPE_TO_INTERCEPTOR_MAP);
-    jsAst.Expression assignment = js('# = #', [typeToInterceptorMap, array]);
-
-    output.addBuffer(jsAst.prettyPrint(assignment, compiler));
-    output.add(N);
+    return js.statement('# = #', [typeToInterceptorMap, array]);
   }
 }
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder.dart
index 8b55f58..4d0e3b2 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder.dart
@@ -332,7 +332,6 @@
       assert(invariant(element, element == enclosing));
 
       if (Elements.isNonAbstractInstanceMember(member)) {
-        js.Expression code = backend.generatedCode[member];
         // TODO(herhut): Remove once _buildMethod can no longer return null.
         Method method = _buildMethod(member);
         if (method != null) methods.add(method);
diff --git a/pkg/compiler/lib/src/js_emitter/registry.dart b/pkg/compiler/lib/src/js_emitter/registry.dart
index d8dfff0..ab7aa52 100644
--- a/pkg/compiler/lib/src/js_emitter/registry.dart
+++ b/pkg/compiler/lib/src/js_emitter/registry.dart
@@ -72,7 +72,6 @@
 
   Registry(this._compiler);
 
-  bool get _isProgramSplit => _deferredLoadTask.isProgramSplit;
   OutputUnit get _mainOutputUnit => _deferredLoadTask.mainOutputUnit;
 
   LibrariesMap _mapUnitToLibrariesMap(OutputUnit targetUnit) {
@@ -119,4 +118,4 @@
         name,
         () => new Holder(name, _holdersMap.length));
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
index 5aa71de..86c95cc 100644
--- a/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
+++ b/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
@@ -44,19 +44,15 @@
     Dart2JsDeclarationMirror owner,
     FunctionSignature signature) {
   var parameters = <ParameterMirror>[];
-  Link<Element> link = signature.requiredParameters;
-  while (!link.isEmpty) {
+  signature.requiredParameters.forEach((FormalElement parameter) {
     parameters.add(new Dart2JsParameterMirror(
-        owner, link.head, isOptional: false, isNamed: false));
-    link = link.tail;
-  }
-  link = signature.optionalParameters;
+        owner, parameter, isOptional: false, isNamed: false));
+  });
   bool isNamed = signature.optionalParametersAreNamed;
-  while (!link.isEmpty) {
+  signature.optionalParameters.forEach((FormalElement parameter) {
     parameters.add(new Dart2JsParameterMirror(
-        owner, link.head, isOptional: true, isNamed: isNamed));
-    link = link.tail;
-  }
+        owner, parameter, isOptional: true, isNamed: isNamed));
+  });
   return parameters;
 }
 
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
index 8ed2a09..1f03ad4 100644
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -193,7 +193,7 @@
       try {
         Token token = parser.parseTopLevelDeclaration(cls.beginToken);
         assert(identical(token, cls.endToken.next));
-      } on ParserError catch (e, s) {
+      } 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.
         compiler.internalError(
@@ -570,4 +570,4 @@
   bool isActive(String patchTag) => tag == null || tag == patchTag;
 
   String toString() => 'PatchVersion($tag)';
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/resolution/access_semantics.dart b/pkg/compiler/lib/src/resolution/access_semantics.dart
index a99db1f..0e1be6f 100644
--- a/pkg/compiler/lib/src/resolution/access_semantics.dart
+++ b/pkg/compiler/lib/src/resolution/access_semantics.dart
@@ -27,18 +27,30 @@
   /// an enclosing function or method.
   LOCAL_FUNCTION,
 
-  /// The destination of the access is a variable that is defined locally within
-  /// an enclosing function or method.
+  /// 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 variable that is defined as a parameter
-  /// to an enclosing function or method.
+  /// 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 field that is defined statically within
-  /// a class.
+  /// 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,
@@ -51,10 +63,14 @@
   /// statically within a class.
   STATIC_SETTER,
 
-  /// The destination of the access is a top level variable defined within a
-  /// library.
+  /// 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,
@@ -91,10 +107,14 @@
   /// of the enclosing class.
   THIS_PROPERTY,
 
-  /// The destination of the access is a field of the super class of the
-  /// enclosing class.
+  /// 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,
@@ -122,16 +142,26 @@
 }
 
 enum CompoundAccessKind {
-  /// Read from a static getter and write to static setter.
+  /// Read from a static getter and write to a static setter.
   STATIC_GETTER_SETTER,
-  /// Read from a static method (closurize) and write to static 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.
@@ -258,6 +288,9 @@
   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);
 
@@ -273,12 +306,21 @@
   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);
 
@@ -291,6 +333,9 @@
   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);
 
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
new file mode 100644
index 0000000..f5534a8
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -0,0 +1,638 @@
+// 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 resolution;
+
+class TypeDefinitionVisitor extends MappingVisitor<DartType> {
+  Scope scope;
+  final TypeDeclarationElement enclosingElement;
+  TypeDeclarationElement get element => enclosingElement;
+
+  TypeDefinitionVisitor(Compiler compiler,
+                        TypeDeclarationElement element,
+                        ResolutionRegistry registry)
+      : this.enclosingElement = element,
+        scope = Scope.buildEnclosingScope(element),
+        super(compiler, registry);
+
+  DartType get objectType => compiler.objectClass.rawType;
+
+  void resolveTypeVariableBounds(NodeList node) {
+    if (node == null) return;
+
+    Setlet<String> nameSet = new Setlet<String>();
+    // Resolve the bounds of type variables.
+    Iterator<DartType> types = element.typeVariables.iterator;
+    Link<Node> nodeLink = node.nodes;
+    while (!nodeLink.isEmpty) {
+      types.moveNext();
+      TypeVariableType typeVariable = types.current;
+      String typeName = typeVariable.name;
+      TypeVariable typeNode = nodeLink.head;
+      registry.useType(typeNode, typeVariable);
+      if (nameSet.contains(typeName)) {
+        error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
+              {'typeVariableName': typeName});
+      }
+      nameSet.add(typeName);
+
+      TypeVariableElementX variableElement = typeVariable.element;
+      if (typeNode.bound != null) {
+        DartType boundType = typeResolver.resolveTypeAnnotation(
+            this, typeNode.bound);
+        variableElement.boundCache = boundType;
+
+        void checkTypeVariableBound() {
+          Link<TypeVariableElement> seenTypeVariables =
+              const Link<TypeVariableElement>();
+          seenTypeVariables = seenTypeVariables.prepend(variableElement);
+          DartType 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.
+                warning(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(Compiler compiler,
+                       ClassElement classElement,
+                       ResolutionRegistry registry)
+    : super(compiler, classElement, registry);
+
+  DartType visitClassNode(ClassNode node) {
+    if (element == null) {
+      throw compiler.internalError(node, 'element is null');
+    }
+    if (element.resolutionState != STATE_STARTED) {
+      throw compiler.internalError(element,
+          'cyclic resolution of class $element');
+    }
+
+    InterfaceType type = element.computeType(compiler);
+    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) {
+        DartType supertype = resolveSupertype(element, superMixin.superclass);
+        Link<Node> link = superMixin.mixins.nodes;
+        while (!link.isEmpty) {
+          supertype = applyMixin(supertype,
+                                 checkMixinType(link.head), link.head);
+          link = link.tail;
+        }
+        element.supertype = supertype;
+      } 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) {
+          compiler.internalError(node,
+              "Cannot resolve default superclass for $element.");
+        } else {
+          superElement.ensureResolved(compiler);
+        }
+        element.supertype = superElement.computeType(compiler);
+      }
+    }
+
+    if (element.interfaces == null) {
+      element.interfaces = resolveInterfaces(node.interfaces, node.superclass);
+    } else {
+      assert(invariant(element, element.hasIncompleteHierarchy));
+    }
+    calculateAllSupertypes(element);
+
+    if (!element.hasConstructor) {
+      Element superMember = element.superclass.localLookup('');
+      if (superMember == null || !superMember.isGenerativeConstructor) {
+        MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR;
+        Map arguments = {'constructorName': ''};
+        // TODO(ahe): Why is this a compile-time error? Or if it is an error,
+        // why do we bother to registerThrowNoSuchMethod below?
+        compiler.reportError(node, kind, arguments);
+        superMember = new ErroneousElementX(
+            kind, arguments, '', element);
+        registry.registerThrowNoSuchMethod();
+      } else {
+        ConstructorElement superConstructor = superMember;
+        Selector callToMatch = new Selector.call("", element.library, 0);
+        superConstructor.computeSignature(compiler);
+        if (!callToMatch.applies(superConstructor, compiler.world)) {
+          MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT;
+          compiler.reportError(node, kind);
+          superMember = new ErroneousElementX(kind, {}, '', element);
+        }
+      }
+      FunctionElement constructor =
+          new SynthesizedConstructorElementX.forDefault(superMember, element);
+      if (superMember.isErroneous) {
+        compiler.elementsWithCompileTimeErrors.add(constructor);
+      }
+      element.setDefaultConstructor(constructor, compiler);
+    }
+    return element.computeType(compiler);
+  }
+
+  @override
+  DartType visitEnum(Enum node) {
+    if (element == null) {
+      throw compiler.internalError(node, 'element is null');
+    }
+    if (element.resolutionState != STATE_STARTED) {
+      throw compiler.internalError(element,
+          'cyclic resolution of class $element');
+    }
+
+    InterfaceType enumType = element.computeType(compiler);
+    element.supertype = compiler.objectClass.computeType(compiler);
+    element.interfaces = const Link<DartType>();
+    calculateAllSupertypes(element);
+
+    if (node.names.nodes.isEmpty) {
+      compiler.reportError(node,
+                           MessageKind.EMPTY_ENUM_DECLARATION,
+                           {'enumName': element.name});
+    }
+
+    EnumCreator creator = new EnumCreator(compiler, element);
+    creator.createMembers();
+    return enumType;
+  }
+
+  /// Resolves the mixed type for [mixinNode] and checks that the the mixin type
+  /// is a valid, non-blacklisted interface type. The mixin type is returned.
+  DartType checkMixinType(TypeAnnotation mixinNode) {
+    DartType mixinType = resolveType(mixinNode);
+    if (isBlackListed(mixinType)) {
+      compiler.reportError(mixinNode,
+          MessageKind.CANNOT_MIXIN, {'type': mixinType});
+    } else if (mixinType.isTypeVariable) {
+      compiler.reportError(mixinNode, MessageKind.CLASS_NAME_EXPECTED);
+    } else if (mixinType.isMalformed) {
+      compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED,
+          {'className': element.name, 'malformedType': mixinType});
+    } else if (mixinType.isEnumType) {
+      compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_ENUM,
+          {'className': element.name, 'enumType': mixinType});
+    }
+    return mixinType;
+  }
+
+  DartType visitNamedMixinApplication(NamedMixinApplication node) {
+    if (element == null) {
+      throw compiler.internalError(node, 'element is null');
+    }
+    if (element.resolutionState != STATE_STARTED) {
+      throw compiler.internalError(element,
+          'cyclic resolution of class $element');
+    }
+
+    if (identical(node.classKeyword.stringValue, 'typedef')) {
+      // TODO(aprelev@gmail.com): Remove this deprecation diagnostic
+      // together with corresponding TODO in parser.dart.
+      compiler.reportWarning(node.classKeyword,
+          MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX);
+    }
+
+    InterfaceType type = element.computeType(compiler);
+    scope = new TypeDeclarationScope(scope, element);
+    resolveTypeVariableBounds(node.typeParameters);
+
+    // Generate anonymous mixin application elements for the
+    // intermediate mixin applications (excluding the last).
+    DartType supertype = resolveSupertype(element, node.superclass);
+    Link<Node> link = node.mixins.nodes;
+    while (!link.tail.isEmpty) {
+      supertype = applyMixin(supertype, checkMixinType(link.head), link.head);
+      link = link.tail;
+    }
+    doApplyMixinTo(element, supertype, checkMixinType(link.head));
+    return element.computeType(compiler);
+  }
+
+  DartType applyMixin(DartType supertype, DartType mixinType, Node node) {
+    String superName = supertype.name;
+    String mixinName = mixinType.name;
+    MixinApplicationElementX mixinApplication = new MixinApplicationElementX(
+        "${superName}+${mixinName}",
+        element.compilationUnit,
+        compiler.getNextFreeClassId(),
+        node,
+        new Modifiers.withFlags(new NodeList.empty(), Modifiers.FLAG_ABSTRACT));
+    // Create synthetic type variables for the mixin application.
+    List<DartType> typeVariables = <DartType>[];
+    element.typeVariables.forEach((TypeVariableType type) {
+      TypeVariableElementX typeVariableElement = new TypeVariableElementX(
+          type.name, mixinApplication, type.element.node);
+      TypeVariableType typeVariable = new TypeVariableType(typeVariableElement);
+      typeVariables.add(typeVariable);
+    });
+    // Setup bounds on the synthetic type variables.
+    int index = 0;
+    element.typeVariables.forEach((TypeVariableType type) {
+      TypeVariableType typeVariable = typeVariables[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(compiler, 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).
+    InterfaceType mixinThisType = mixinApplication.computeType(compiler);
+    return mixinThisType.subst(element.typeVariables,
+                               mixinThisType.typeArguments);
+  }
+
+  bool isDefaultConstructor(FunctionElement constructor) {
+    return constructor.name == '' &&
+        constructor.computeSignature(compiler).parameterCount == 0;
+  }
+
+  FunctionElement createForwardingConstructor(ConstructorElement target,
+                                              ClassElement enclosing) {
+    return new SynthesizedConstructorElementX.notForDefault(
+        target.name, target, enclosing);
+  }
+
+  void doApplyMixinTo(MixinApplicationElementX mixinApplication,
+                      DartType supertype,
+                      DartType mixinType) {
+    Node node = mixinApplication.parseNode(compiler);
+
+    if (mixinApplication.supertype != null) {
+      // [supertype] is not null if there was a cycle.
+      assert(invariant(node, compiler.compilationFailed));
+      supertype = mixinApplication.supertype;
+      assert(invariant(node, supertype.element == compiler.objectClass));
+    } else {
+      mixinApplication.supertype = supertype;
+    }
+
+    // Named mixin application may have an 'implements' clause.
+    NamedMixinApplication namedMixinApplication =
+        node.asNamedMixinApplication();
+    Link<DartType> interfaces = (namedMixinApplication != null)
+        ? resolveInterfaces(namedMixinApplication.interfaces,
+                            namedMixinApplication.superclass)
+        : const Link<DartType>();
+
+    // 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(invariant(mixinApplication,
+          mixinApplication.hasIncompleteHierarchy));
+    }
+
+    ClassElement superclass = supertype.element;
+    if (mixinType.kind != TypeKind.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 (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);
+  }
+
+  InterfaceType resolveMixinFor(MixinApplicationElement mixinApplication,
+                                DartType mixinType) {
+    ClassElement mixin = mixinType.element;
+    mixin.ensureResolved(compiler);
+
+    // 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) {
+        compiler.reportError(
+            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;
+    }
+    registry.registerMixinUse(mixinApplication, mixin);
+    return mixinType;
+  }
+
+  DartType resolveType(TypeAnnotation node) {
+    return typeResolver.resolveTypeAnnotation(this, node);
+  }
+
+  DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) {
+    DartType supertype = resolveType(superclass);
+    if (supertype != null) {
+      if (supertype.isMalformed) {
+        compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_MALFORMED,
+            {'className': element.name, 'malformedType': supertype});
+        return objectType;
+      } else if (supertype.isEnumType) {
+        compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_ENUM,
+            {'className': element.name, 'enumType': supertype});
+        return objectType;
+      } else if (!supertype.isInterfaceType) {
+        compiler.reportError(superclass.typeName,
+            MessageKind.CLASS_NAME_EXPECTED);
+        return objectType;
+      } else if (isBlackListed(supertype)) {
+        compiler.reportError(superclass, MessageKind.CANNOT_EXTEND,
+            {'type': supertype});
+        return objectType;
+      }
+    }
+    return supertype;
+  }
+
+  Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) {
+    Link<DartType> result = const Link<DartType>();
+    if (interfaces == null) return result;
+    for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) {
+      DartType interfaceType = resolveType(link.head);
+      if (interfaceType != null) {
+        if (interfaceType.isMalformed) {
+          compiler.reportError(superclass,
+              MessageKind.CANNOT_IMPLEMENT_MALFORMED,
+              {'className': element.name, 'malformedType': interfaceType});
+        } else if (interfaceType.isEnumType) {
+          compiler.reportError(superclass,
+              MessageKind.CANNOT_IMPLEMENT_ENUM,
+              {'className': element.name, 'enumType': interfaceType});
+        } else if (!interfaceType.isInterfaceType) {
+          // TODO(johnniwinther): Handle dynamic.
+          TypeAnnotation typeAnnotation = link.head;
+          error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED);
+        } else {
+          if (interfaceType == element.supertype) {
+            compiler.reportError(
+                superclass,
+                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
+                {'type': interfaceType});
+            compiler.reportError(
+                link.head,
+                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
+                {'type': interfaceType});
+          }
+          if (result.contains(interfaceType)) {
+            compiler.reportError(
+                link.head,
+                MessageKind.DUPLICATE_IMPLEMENTS,
+                {'type': interfaceType});
+          }
+          result = result.prepend(interfaceType);
+          if (isBlackListed(interfaceType)) {
+            error(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 DartType supertype = cls.supertype;
+    if (supertype != null) {
+      OrderedTypeSetBuilder allSupertypes = new OrderedTypeSetBuilder(cls);
+      // TODO(15296): Collapse these iterations to one when the order is not
+      // needed.
+      allSupertypes.add(compiler, supertype);
+      for (Link<DartType> interfaces = cls.interfaces;
+           !interfaces.isEmpty;
+           interfaces = interfaces.tail) {
+        allSupertypes.add(compiler, interfaces.head);
+      }
+
+      addAllSupertypes(allSupertypes, supertype);
+      for (Link<DartType> interfaces = cls.interfaces;
+           !interfaces.isEmpty;
+           interfaces = interfaces.tail) {
+        addAllSupertypes(allSupertypes, interfaces.head);
+      }
+      allSupertypes.add(compiler, cls.computeType(compiler));
+      cls.allSupertypesAndSelf = allSupertypes.toTypeSet();
+    } else {
+      assert(identical(cls, compiler.objectClass));
+      cls.allSupertypesAndSelf =
+          new OrderedTypeSet.singleton(cls.computeType(compiler));
+    }
+  }
+
+  /**
+   * Adds [type] and all supertypes of [type] to [allSupertypes] while
+   * substituting type variables.
+   */
+  void addAllSupertypes(OrderedTypeSetBuilder allSupertypes,
+                        InterfaceType type) {
+    ClassElement classElement = type.element;
+    Link<DartType> supertypes = classElement.allSupertypes;
+    assert(invariant(element, supertypes != null,
+        message: "Supertypes not computed on $classElement "
+                 "during resolution of $element"));
+    while (!supertypes.isEmpty) {
+      DartType supertype = supertypes.head;
+      allSupertypes.add(compiler, supertype.substByContext(type));
+      supertypes = supertypes.tail;
+    }
+  }
+
+  isBlackListed(DartType type) {
+    LibraryElement lib = element.library;
+    return
+      !identical(lib, compiler.coreLibrary) &&
+      !compiler.backend.isBackendLibrary(lib) &&
+      (type.isDynamic ||
+       identical(type.element, compiler.boolClass) ||
+       identical(type.element, compiler.numClass) ||
+       identical(type.element, compiler.intClass) ||
+       identical(type.element, compiler.doubleClass) ||
+       identical(type.element, compiler.stringClass) ||
+       identical(type.element, compiler.nullClass));
+  }
+}
+
+class ClassSupertypeResolver extends CommonResolverVisitor {
+  Scope context;
+  ClassElement classElement;
+
+  ClassSupertypeResolver(Compiler compiler, ClassElement cls)
+    : context = Scope.buildEnclosingScope(cls),
+      this.classElement = cls,
+      super(compiler);
+
+  void loadSupertype(ClassElement element, Node from) {
+    compiler.resolver.loadSupertypes(element, from);
+    element.ensureResolved(compiler);
+  }
+
+  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 (!identical(classElement, compiler.objectClass)) {
+        loadSupertype(compiler.objectClass, node);
+      }
+    } else {
+      node.superclass.accept(this);
+    }
+    visitNodeList(node.interfaces);
+  }
+
+  void visitEnum(Enum node) {
+    loadSupertype(compiler.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 visitTypeAnnotation(TypeAnnotation node) {
+    node.typeName.accept(this);
+  }
+
+  void visitIdentifier(Identifier node) {
+    Element element = lookupInScope(compiler, node, context, node.source);
+    if (element != null && element.isClass) {
+      loadSupertype(element, node);
+    }
+  }
+
+  void visitSend(Send node) {
+    Identifier prefix = node.receiver.asIdentifier();
+    if (prefix == null) {
+      error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
+      return;
+    }
+    Element element = lookupInScope(compiler, prefix, context, prefix.source);
+    if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
+      error(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) {
+      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE,
+            {'typeName': node.selector});
+      return;
+    }
+    loadSupertype(e, node);
+  }
+}
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
new file mode 100644
index 0000000..28d5a3b
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -0,0 +1,478 @@
+// 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 resolution;
+
+class InitializerResolver {
+  final ResolverVisitor visitor;
+  final Map<Element, Node> initialized;
+  Link<Node> initializers;
+  bool hasSuper;
+
+  InitializerResolver(this.visitor)
+    : initialized = new Map<Element, Node>(), hasSuper = false;
+
+  ResolutionRegistry get registry => visitor.registry;
+
+  error(Node node, MessageKind kind, [arguments = const {}]) {
+    visitor.error(node, kind, arguments);
+  }
+
+  warning(Node node, MessageKind kind, [arguments = const {}]) {
+    visitor.warning(node, kind, arguments);
+  }
+
+  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, Node existing) {
+    visitor.compiler.reportError(
+        init,
+        MessageKind.DUPLICATE_INITIALIZER, {'fieldName': field.name});
+    visitor.compiler.reportInfo(
+        existing,
+        MessageKind.ALREADY_INITIALIZED, {'fieldName': field.name});
+  }
+
+  void checkForDuplicateInitializers(FieldElementX field, Node init) {
+    // [field] can be null if it could not be resolved.
+    if (field == null) return;
+    String name = field.name;
+    if (initialized.containsKey(field)) {
+      reportDuplicateInitializerError(field, init, initialized[field]);
+    } else if (field.isFinal) {
+      field.parseNode(visitor.compiler);
+      Expression initializer = field.initializer;
+      if (initializer != null) {
+        reportDuplicateInitializerError(field, init, initializer);
+      }
+    }
+    initialized[field] = init;
+  }
+
+  void resolveFieldInitializer(FunctionElement constructor, 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;
+    if (isFieldInitializer(init)) {
+      target = constructor.enclosingClass.lookupLocalMember(name);
+      if (target == null) {
+        error(selector, MessageKind.CANNOT_RESOLVE, {'name': name});
+        target = new ErroneousFieldElementX(
+            selector.asIdentifier(), constructor.enclosingClass);
+      } else if (target.kind != ElementKind.FIELD) {
+        error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name});
+        target = new ErroneousFieldElementX(
+            selector.asIdentifier(), constructor.enclosingClass);
+      } else if (!target.isInstanceMember) {
+        error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name});
+      }
+    } else {
+      error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
+    }
+    registry.useElement(init, target);
+    registry.registerStaticUse(target);
+    checkForDuplicateInitializers(target, init);
+    // Resolve initializing value.
+    visitor.visitInStaticContext(init.arguments.head);
+  }
+
+  ClassElement getSuperOrThisLookupTarget(FunctionElement constructor,
+                                          bool isSuperCall,
+                                          Node diagnosticNode) {
+    ClassElement lookupTarget = constructor.enclosingClass;
+    if (isSuperCall) {
+      // Calculate correct lookup target and constructor name.
+      if (identical(lookupTarget, visitor.compiler.objectClass)) {
+        error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
+      } else {
+        return lookupTarget.supertype.element;
+      }
+    }
+    return lookupTarget;
+  }
+
+  Element resolveSuperOrThisForSend(FunctionElement constructor,
+                                    FunctionExpression functionNode,
+                                    Send call) {
+    // Resolve the selector and the arguments.
+    ResolverTask resolver = visitor.compiler.resolver;
+    visitor.inStaticContext(() {
+      visitor.resolveSelector(call, null);
+      visitor.resolveArguments(call.argumentsNode);
+    });
+    Selector selector = registry.getSelector(call);
+    bool isSuperCall = Initializers.isSuperConstructorCall(call);
+
+    ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
+                                                           isSuperCall,
+                                                           call);
+    Selector constructorSelector =
+        visitor.getRedirectingThisOrSuperConstructorSelector(call);
+    FunctionElement calledConstructor =
+        lookupTarget.lookupConstructor(constructorSelector.name);
+
+    final bool isImplicitSuperCall = false;
+    final String className = lookupTarget.name;
+    verifyThatConstructorMatchesCall(constructor,
+                                     calledConstructor,
+                                     selector.callStructure,
+                                     isImplicitSuperCall,
+                                     call,
+                                     className,
+                                     constructorSelector);
+
+    registry.useElement(call, calledConstructor);
+    registry.registerStaticUse(calledConstructor);
+    return calledConstructor;
+  }
+
+  void resolveImplicitSuperConstructorSend(FunctionElement constructor,
+                                           FunctionExpression functionNode) {
+    // If the class has a super resolve the implicit super call.
+    ClassElement classElement = constructor.enclosingClass;
+    ClassElement superClass = classElement.superclass;
+    if (classElement != visitor.compiler.objectClass) {
+      assert(superClass != null);
+      assert(superClass.resolutionState == STATE_DONE);
+
+      final bool isSuperCall = true;
+      ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
+                                                             isSuperCall,
+                                                             functionNode);
+      Selector constructorSelector = new Selector.callDefaultConstructor();
+      Element calledConstructor = lookupTarget.lookupConstructor(
+          constructorSelector.name);
+
+      final String className = lookupTarget.name;
+      final bool isImplicitSuperCall = true;
+      verifyThatConstructorMatchesCall(constructor,
+                                       calledConstructor,
+                                       CallStructure.NO_ARGS,
+                                       isImplicitSuperCall,
+                                       functionNode,
+                                       className,
+                                       constructorSelector);
+      registry.registerImplicitSuperCall(calledConstructor);
+      registry.registerStaticUse(calledConstructor);
+    }
+  }
+
+  void verifyThatConstructorMatchesCall(
+      FunctionElement caller,
+      ConstructorElementX lookedupConstructor,
+      CallStructure call,
+      bool isImplicitSuperCall,
+      Node diagnosticNode,
+      String className,
+      Selector constructorSelector) {
+    if (lookedupConstructor == null
+        || !lookedupConstructor.isGenerativeConstructor) {
+      String fullConstructorName = Elements.constructorNameForDiagnostics(
+              className,
+              constructorSelector.name);
+      MessageKind kind = isImplicitSuperCall
+          ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
+          : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
+      visitor.compiler.reportError(
+          diagnosticNode, kind, {'constructorName': fullConstructorName});
+    } else {
+      lookedupConstructor.computeSignature(visitor.compiler);
+      if (!call.signatureApplies(lookedupConstructor)) {
+        MessageKind kind = isImplicitSuperCall
+                           ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
+                           : MessageKind.NO_MATCHING_CONSTRUCTOR;
+        visitor.compiler.reportError(diagnosticNode, kind);
+      } else if (caller.isConst
+                 && !lookedupConstructor.isConst) {
+        visitor.compiler.reportError(
+            diagnosticNode, MessageKind.CONST_CALLS_NON_CONST);
+      }
+    }
+  }
+
+  /**
+   * Resolve all initializers of this constructor. In the case of a redirecting
+   * constructor, the resolved constructor's function element is returned.
+   */
+  ConstructorElement resolveInitializers(ConstructorElementX constructor,
+                                         FunctionExpression functionNode) {
+    // 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;
+    functionParameters.forEachParameter((ParameterElement element) {
+      if (element.isInitializingFormal) {
+        InitializingFormalElement initializingFormal = element;
+        checkForDuplicateInitializers(initializingFormal.fieldElement,
+                                      element.initializer);
+      }
+    });
+
+    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(constructor, init);
+      } else if (link.head.asSend() != null) {
+        final Send call = link.head.asSend();
+        if (call.argumentsNode == null) {
+          error(link.head, MessageKind.INVALID_INITIALIZER);
+          continue;
+        }
+        if (Initializers.isSuperConstructorCall(call)) {
+          if (resolvedSuper) {
+            error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER);
+          }
+          resolveSuperOrThisForSend(constructor, functionNode, call);
+          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) {
+            error(functionNode, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY);
+          }
+          // Check that there are no other initializers.
+          if (!initializers.tail.isEmpty) {
+            error(call, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER);
+          } else {
+            constructor.isRedirectingGenerative = true;
+          }
+          // Check that there are no field initializing parameters.
+          Compiler compiler = visitor.compiler;
+          FunctionSignature signature = constructor.functionSignature;
+          signature.forEachParameter((ParameterElement parameter) {
+            if (parameter.isInitializingFormal) {
+              Node node = parameter.node;
+              error(node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED);
+            }
+          });
+          return resolveSuperOrThisForSend(constructor, functionNode, call);
+        } else {
+          visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED);
+          return null;
+        }
+      } else {
+        error(link.head, MessageKind.INVALID_INITIALIZER);
+      }
+    }
+    if (!resolvedSuper) {
+      resolveImplicitSuperConstructorSend(constructor, functionNode);
+    }
+    return null;  // If there was no redirection always return null.
+  }
+}
+
+class ConstructorResolver extends CommonResolverVisitor<Element> {
+  final ResolverVisitor resolver;
+  bool inConstContext;
+  DartType type;
+
+  ConstructorResolver(Compiler compiler, this.resolver,
+                      {bool this.inConstContext: false})
+      : super(compiler);
+
+  ResolutionRegistry get registry => resolver.registry;
+
+  visitNode(Node node) {
+    throw 'not supported';
+  }
+
+  ErroneousConstructorElementX failOrReturnErroneousConstructorElement(
+      Spannable diagnosticNode,
+      Element enclosing,
+      String name,
+      MessageKind kind,
+      Map arguments,
+      {bool isError: false,
+       bool missingConstructor: false}) {
+    if (missingConstructor) {
+      registry.registerThrowNoSuchMethod();
+    } else {
+      registry.registerThrowRuntimeError();
+    }
+    if (isError || inConstContext) {
+      compiler.reportError(diagnosticNode, kind, arguments);
+    } else {
+      compiler.reportWarning(diagnosticNode, kind, arguments);
+    }
+    return new ErroneousConstructorElementX(
+        kind, arguments, name, enclosing);
+  }
+
+  FunctionElement resolveConstructor(ClassElement cls,
+                                     Node diagnosticNode,
+                                     String constructorName) {
+    cls.ensureResolved(compiler);
+    Element result = cls.lookupConstructor(constructorName);
+    // TODO(johnniwinther): Use [Name] for lookup.
+    if (isPrivateName(constructorName) &&
+        resolver.enclosingElement.library != cls.library) {
+      result = null;
+    }
+    if (result == null) {
+      String fullConstructorName = Elements.constructorNameForDiagnostics(
+              cls.name,
+              constructorName);
+      return failOrReturnErroneousConstructorElement(
+          diagnosticNode,
+          cls, constructorName,
+          MessageKind.CANNOT_FIND_CONSTRUCTOR,
+          {'constructorName': fullConstructorName},
+          missingConstructor: true);
+    } else if (inConstContext && !result.isConst) {
+      error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
+    }
+    return result;
+  }
+
+  Element visitNewExpression(NewExpression node) {
+    inConstContext = node.isConst;
+    Node selector = node.send.selector;
+    Element element = visit(selector);
+    assert(invariant(selector, element != null,
+        message: 'No element return for $selector.'));
+    return finishConstructorReference(element, node.send.selector, node);
+  }
+
+  /// Finishes resolution of a constructor reference and records the
+  /// type of the constructed instance on [expression].
+  FunctionElement finishConstructorReference(Element element,
+                                             Node diagnosticNode,
+                                             Node expression) {
+    assert(invariant(diagnosticNode, element != null,
+        message: 'No element return for $diagnosticNode.'));
+    // Find the unnamed constructor if the reference resolved to a
+    // class.
+    if (!Elements.isUnresolved(element) && !element.isConstructor) {
+      if (element.isClass) {
+        ClassElement cls = element;
+        cls.ensureResolved(compiler);
+        // The unnamed constructor may not exist, so [e] may become unresolved.
+        element = resolveConstructor(cls, diagnosticNode, '');
+      } else {
+        element = failOrReturnErroneousConstructorElement(
+            diagnosticNode,
+            element, element.name,
+            MessageKind.NOT_A_TYPE, {'node': diagnosticNode});
+      }
+    } else if (element.isErroneous && element is! ErroneousElementX) {
+      // Parser error. The error has already been reported.
+      element = new ErroneousConstructorElementX(
+          MessageKind.NOT_A_TYPE, {'node': diagnosticNode},
+          element.name, element);
+      registry.registerThrowRuntimeError();
+    }
+
+    if (type == null) {
+      if (Elements.isUnresolved(element)) {
+        type = const DynamicType();
+      } else {
+        type = element.enclosingClass.rawType;
+      }
+    }
+    resolver.registry.setType(expression, type);
+    return element;
+  }
+
+  Element visitTypeAnnotation(TypeAnnotation node) {
+    assert(invariant(node, type == null));
+    // This is not really resolving a type-annotation, but the name of the
+    // constructor. Therefore we allow deferred types.
+    type = resolver.resolveTypeAnnotation(node,
+                                          malformedIsError: inConstContext,
+                                          deferredIsMalformed: false);
+    registry.registerRequiredType(type, resolver.enclosingElement);
+    return type.element;
+  }
+
+  Element visitSend(Send node) {
+    Element element = visit(node.receiver);
+    assert(invariant(node.receiver, element != null,
+        message: 'No element return for $node.receiver.'));
+    if (Elements.isUnresolved(element)) return element;
+    Identifier name = node.selector.asIdentifier();
+    if (name == null) internalError(node.selector, 'unexpected node');
+
+    if (element.isClass) {
+      ClassElement cls = element;
+      cls.ensureResolved(compiler);
+      return resolveConstructor(cls, name, name.source);
+    } else if (element.isPrefix) {
+      PrefixElement prefix = element;
+      element = prefix.lookupLocalMember(name.source);
+      element = Elements.unwrap(element, compiler, node);
+      if (element == null) {
+        return failOrReturnErroneousConstructorElement(
+            name,
+            resolver.enclosingElement, name.source,
+            MessageKind.CANNOT_RESOLVE, {'name': name});
+      } else if (!element.isClass) {
+        return failOrReturnErroneousConstructorElement(
+            name,
+            resolver.enclosingElement, name.source,
+            MessageKind.NOT_A_TYPE, {'node': name},
+            isError: true);
+      }
+    } else {
+      internalError(node.receiver, 'unexpected element $element');
+    }
+    return element;
+  }
+
+  Element visitIdentifier(Identifier node) {
+    String name = node.source;
+    Element element = resolver.reportLookupErrorIfAny(
+        lookupInScope(compiler, node, resolver.scope, name), node, name);
+    registry.useElement(node, element);
+    // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1.
+    if (element == null) {
+      return failOrReturnErroneousConstructorElement(
+          node,
+          resolver.enclosingElement, name,
+          MessageKind.CANNOT_RESOLVE,
+          {'name': name});
+    } else if (element.isErroneous) {
+      return element;
+    } else if (element.isTypedef) {
+      element = failOrReturnErroneousConstructorElement(
+          node,
+          resolver.enclosingElement, name,
+          MessageKind.CANNOT_INSTANTIATE_TYPEDEF, {'typedefName': name},
+          isError: true);
+    } else if (element.isTypeVariable) {
+      element = failOrReturnErroneousConstructorElement(
+          node,
+          resolver.enclosingElement, name,
+          MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
+          {'typeVariableName': name},
+          isError: true);
+    } else if (!element.isClass && !element.isPrefix) {
+      element = failOrReturnErroneousConstructorElement(
+          node,
+          resolver.enclosingElement, name,
+          MessageKind.NOT_A_TYPE, {'node': name},
+          isError: true);
+    }
+    return element;
+  }
+
+  /// Assumed to be called by [resolveRedirectingFactory].
+  Element visitRedirectingFactoryBody(RedirectingFactoryBody node) {
+    Node constructorReference = node.constructorReference;
+    return finishConstructorReference(visit(constructorReference),
+        constructorReference, node);
+  }
+}
diff --git a/pkg/compiler/lib/src/resolution/enum_creator.dart b/pkg/compiler/lib/src/resolution/enum_creator.dart
index fc9ee70..d68e961 100644
--- a/pkg/compiler/lib/src/resolution/enum_creator.dart
+++ b/pkg/compiler/lib/src/resolution/enum_creator.dart
@@ -221,7 +221,7 @@
         indexVariable);
 
     FunctionSignatureX constructorSignature = new FunctionSignatureX(
-        requiredParameters: builder.linkedList([indexFormal]),
+        requiredParameters: [indexFormal],
         requiredParameterCount: 1,
         type: new FunctionType(constructor, const VoidType(),
             <DartType>[intType]));
diff --git a/pkg/compiler/lib/src/resolution/label_scope.dart b/pkg/compiler/lib/src/resolution/label_scope.dart
new file mode 100644
index 0000000..c02c07e
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/label_scope.dart
@@ -0,0 +1,101 @@
+// 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 resolution;
+
+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/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 6973a47..0ea0739 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -4,2100 +4,6 @@
 
 part of resolution;
 
-abstract class TreeElements {
-  AnalyzableElement get analyzedElement;
-  Iterable<Node> get superUses;
-
-  /// Iterables of the dependencies that this [TreeElement] records of
-  /// [analyzedElement].
-  Iterable<Element> get allElements;
-  void forEachConstantNode(f(Node n, ConstantExpression c));
-
-  /// A set of additional dependencies.  See [registerDependency] below.
-  Iterable<Element> get otherDependencies;
-
-  Element operator[](Node node);
-
-  // TODO(johnniwinther): Investigate whether [Node] could be a [Send].
-  Selector getSelector(Node node);
-  Selector getGetterSelectorInComplexSendSet(SendSet node);
-  Selector getOperatorSelectorInComplexSendSet(SendSet node);
-  DartType getType(Node node);
-  void setSelector(Node node, Selector selector);
-  void setGetterSelectorInComplexSendSet(SendSet node, Selector selector);
-  void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector);
-
-  /// Returns the for-in loop variable for [node].
-  Element getForInVariable(ForIn node);
-  Selector getIteratorSelector(ForIn node);
-  Selector getMoveNextSelector(ForIn node);
-  Selector getCurrentSelector(ForIn node);
-  void setIteratorSelector(ForIn node, Selector selector);
-  void setMoveNextSelector(ForIn node, Selector selector);
-  void setCurrentSelector(ForIn node, Selector selector);
-  void setConstant(Node node, ConstantExpression constant);
-  ConstantExpression getConstant(Node node);
-  bool isAssert(Send send);
-
-  /// 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.
-  DartType getTypeLiteralType(Send node);
-
-  /// Register additional dependencies required by [analyzedElement].
-  /// For example, elements that are used by a backend.
-  void registerDependency(Element element);
-
-  /// 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);
-}
-
-class TreeElementMapping implements TreeElements {
-  final AnalyzableElement analyzedElement;
-  Map<Spannable, Selector> _selectors;
-  Map<Node, DartType> _types;
-  Setlet<Node> _superUses;
-  Setlet<Element> _otherDependencies;
-  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;
-  Setlet<Element> _elements;
-  Setlet<Send> _asserts;
-
-  /// 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;
-
-  final int hashCode = ++_hashCodeCounter;
-  static int _hashCodeCounter = 0;
-
-  TreeElementMapping(this.analyzedElement);
-
-  operator []=(Node node, Element element) {
-    // TODO(johnniwinther): Simplify this invariant to use only declarations in
-    // [TreeElements].
-    assert(invariant(node, () {
-      if (!element.isErroneous && analyzedElement != null && element.isPatch) {
-        return analyzedElement.implementationLibrary.isPatch;
-      }
-      return true;
-    }));
-    // TODO(ahe): Investigate why the invariant below doesn't hold.
-    // assert(invariant(node,
-    //                  getTreeElement(node) == element ||
-    //                  getTreeElement(node) == null,
-    //                  message: '${getTreeElement(node)}; $element'));
-
-    if (_elements == null) {
-      _elements = new Setlet<Element>();
-    }
-    _elements.add(element);
-    setTreeElement(node, element);
-  }
-
-  operator [](Node node) => getTreeElement(node);
-
-  void setType(Node node, DartType type) {
-    if (_types == null) {
-      _types = new Maplet<Node, DartType>();
-    }
-    _types[node] = type;
-  }
-
-  DartType getType(Node node) => _types != null ? _types[node] : null;
-
-  Iterable<Node> get superUses {
-    return _superUses != null ? _superUses : const <Node>[];
-  }
-
-  void addSuperUse(Node node) {
-    if (_superUses == null) {
-      _superUses = new Setlet<Node>();
-    }
-    _superUses.add(node);
-  }
-
-  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);
-  }
-
-  Selector getSelector(Node node) => _getSelector(node);
-
-  int getSelectorCount() => _selectors == null ? 0 : _selectors.length;
-
-  void setGetterSelectorInComplexSendSet(SendSet node, Selector selector) {
-    _setSelector(node.selector, selector);
-  }
-
-  Selector getGetterSelectorInComplexSendSet(SendSet node) {
-    return _getSelector(node.selector);
-  }
-
-  void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector) {
-    _setSelector(node.assignmentOperator, selector);
-  }
-
-  Selector getOperatorSelectorInComplexSendSet(SendSet node) {
-    return _getSelector(node.assignmentOperator);
-  }
-
-  // The following methods set selectors on the "for in" node. Since
-  // we're using three selectors, we need to use children of the node,
-  // and we arbitrarily choose which ones.
-
-  void setIteratorSelector(ForIn node, Selector selector) {
-    _setSelector(node, selector);
-  }
-
-  Selector getIteratorSelector(ForIn node) {
-    return _getSelector(node);
-  }
-
-  void setMoveNextSelector(ForIn node, Selector selector) {
-    _setSelector(node.forToken, selector);
-  }
-
-  Selector getMoveNextSelector(ForIn node) {
-    return _getSelector(node.forToken);
-  }
-
-  void setCurrentSelector(ForIn node, Selector selector) {
-    _setSelector(node.inToken, selector);
-  }
-
-  Selector getCurrentSelector(ForIn node) {
-    return _getSelector(node.inToken);
-  }
-
-  Element getForInVariable(ForIn node) {
-    return this[node];
-  }
-
-  void setConstant(Node node, ConstantExpression constant) {
-    if (_constants == null) {
-      _constants = new Maplet<Node, ConstantExpression>();
-    }
-    _constants[node] = constant;
-  }
-
-  ConstantExpression getConstant(Node node) {
-    return _constants != null ? _constants[node] : null;
-  }
-
-  bool isTypeLiteral(Send node) {
-    return getType(node) != null;
-  }
-
-  DartType getTypeLiteralType(Send node) {
-    return getType(node);
-  }
-
-  void registerDependency(Element element) {
-    if (element == null) return;
-    if (_otherDependencies == null) {
-      _otherDependencies = new Setlet<Element>();
-    }
-    _otherDependencies.add(element.implementation);
-  }
-
-  Iterable<Element> get otherDependencies {
-    return _otherDependencies != null ? _otherDependencies : const <Element>[];
-  }
-
-  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);
-  }
-
-  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);
-  }
-
-  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);
-  }
-
-  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)';
-
-  Iterable<Element> get allElements {
-    return _elements != null ? _elements : const <Element>[];
-  }
-
-  void forEachConstantNode(f(Node n, ConstantExpression c)) {
-    if (_constants != null) {
-      _constants.forEach(f);
-    }
-  }
-
-  void setAssert(Send node) {
-    if (_asserts == null) {
-      _asserts = new Setlet<Send>();
-    }
-    _asserts.add(node);
-  }
-
-  bool isAssert(Send node) {
-    return _asserts != null && _asserts.contains(node);
-  }
-
-  FunctionElement getFunctionDefinition(FunctionExpression node) {
-    return this[node];
-  }
-
-  ConstructorElement getRedirectingTargetConstructor(
-      RedirectingFactoryBody node) {
-    return this[node];
-  }
-
-  void defineTarget(Node node, JumpTarget target) {
-    if (_definedTargets == null) {
-      _definedTargets = new Maplet<Node, JumpTarget>();
-    }
-    _definedTargets[node] = target;
-  }
-
-  void undefineTarget(Node node) {
-    if (_definedTargets != null) {
-      _definedTargets.remove(node);
-      if (_definedTargets.isEmpty) {
-        _definedTargets = null;
-      }
-    }
-  }
-
-  JumpTarget getTargetDefinition(Node node) {
-    return _definedTargets != null ? _definedTargets[node] : null;
-  }
-
-  void registerTargetOf(GotoStatement node, JumpTarget target) {
-    if (_usedTargets == null) {
-      _usedTargets = new Maplet<GotoStatement, JumpTarget>();
-    }
-    _usedTargets[node] = target;
-  }
-
-  JumpTarget getTargetOf(GotoStatement node) {
-    return _usedTargets != null ? _usedTargets[node] : null;
-  }
-
-  void defineLabel(Label label, LabelDefinition target) {
-    if (_definedLabels == null) {
-      _definedLabels = new Maplet<Label, LabelDefinition>();
-    }
-    _definedLabels[label] = target;
-  }
-
-  void undefineLabel(Label label) {
-    if (_definedLabels != null) {
-      _definedLabels.remove(label);
-      if (_definedLabels.isEmpty) {
-        _definedLabels = null;
-      }
-    }
-  }
-
-  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;
-  }
-
-  LabelDefinition getTargetLabel(GotoStatement node) {
-    assert(node.target != null);
-    return _targetLabels != null ? _targetLabels[node] : null;
-  }
-}
-
-class ResolverTask extends CompilerTask {
-  final ConstantCompiler constantCompiler;
-
-  ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler);
-
-  String get name => 'Resolver';
-
-  TreeElements resolve(Element element) {
-    return measure(() {
-      if (Elements.isErroneous(element)) return null;
-
-      processMetadata([result]) {
-        for (MetadataAnnotation metadata in element.metadata) {
-          metadata.ensureResolved(compiler);
-        }
-        return result;
-      }
-
-      ElementKind kind = element.kind;
-      if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) ||
-          identical(kind, ElementKind.FUNCTION) ||
-          identical(kind, ElementKind.GETTER) ||
-          identical(kind, ElementKind.SETTER)) {
-        return processMetadata(resolveMethodElement(element));
-      }
-
-      if (identical(kind, ElementKind.FIELD)) {
-        return processMetadata(resolveField(element));
-      }
-      if (element.isClass) {
-        ClassElement cls = element;
-        cls.ensureResolved(compiler);
-        return processMetadata();
-      } else if (element.isTypedef) {
-        TypedefElement typdef = element;
-        return processMetadata(resolveTypedef(typdef));
-      }
-
-      compiler.unimplemented(element, "resolve($element)");
-    });
-  }
-
-  void resolveRedirectingConstructor(InitializerResolver resolver,
-                                     Node node,
-                                     FunctionElement constructor,
-                                     FunctionElement redirection) {
-    assert(invariant(node, constructor.isImplementation,
-        message: '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 (seen.contains(redirection)) {
-        resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
-        return;
-      }
-      seen.add(redirection);
-      redirection = resolver.visitor.resolveConstructorRedirection(redirection);
-    }
-  }
-
-  static void processAsyncMarker(Compiler compiler,
-                                 BaseFunctionElementX element,
-                                 Registry registry) {
-    FunctionExpression functionExpression = element.node;
-    AsyncModifier asyncModifier = functionExpression.asyncModifier;
-    if (asyncModifier != null) {
-
-      if (asyncModifier.isAsynchronous) {
-        element.asyncMarker = asyncModifier.isYielding
-            ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC;
-      } else {
-        element.asyncMarker = AsyncMarker.SYNC_STAR;
-      }
-      if (element.isAbstract) {
-        compiler.reportError(asyncModifier,
-            MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
-            {'modifier': element.asyncMarker});
-      } else if (element.isConstructor) {
-        compiler.reportError(asyncModifier,
-            MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
-            {'modifier': element.asyncMarker});
-      } else {
-        if (element.isSetter) {
-          compiler.reportError(asyncModifier,
-              MessageKind.ASYNC_MODIFIER_ON_SETTER,
-              {'modifier': element.asyncMarker});
-
-        }
-        if (functionExpression.body.asReturn() != null &&
-            element.asyncMarker.isYielding) {
-          compiler.reportError(asyncModifier,
-              MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
-              {'modifier': element.asyncMarker});
-        }
-      }
-      registry.registerAsyncMarker(element);
-      switch (element.asyncMarker) {
-      case AsyncMarker.ASYNC:
-        compiler.futureClass.ensureResolved(compiler);
-        break;
-      case AsyncMarker.ASYNC_STAR:
-        compiler.streamClass.ensureResolved(compiler);
-        break;
-      case AsyncMarker.SYNC_STAR:
-        compiler.iterableClass.ensureResolved(compiler);
-        break;
-      }
-    }
-  }
-
-  bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) {
-    assert(classElement != null);
-    while (classElement != null) {
-      if (classElement.isNative) return true;
-      classElement = classElement.superclass;
-    }
-    return false;
-  }
-
-  TreeElements resolveMethodElementImplementation(
-      FunctionElement element, FunctionExpression tree) {
-    return compiler.withCurrentElement(element, () {
-      if (element.isExternal && tree.hasBody()) {
-        error(element,
-            MessageKind.EXTERNAL_WITH_BODY,
-            {'functionName': element.name});
-      }
-      if (element.isConstructor) {
-        if (tree.returnType != null) {
-          error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
-        }
-        if (element.isConst &&
-            tree.hasBody() &&
-            !tree.isRedirectingFactory) {
-          error(tree, MessageKind.CONST_CONSTRUCTOR_HAS_BODY);
-        }
-      }
-
-      ResolverVisitor visitor = visitorFor(element);
-      ResolutionRegistry registry = visitor.registry;
-      registry.defineFunction(tree, element);
-      visitor.setupFunction(tree, element);
-      processAsyncMarker(compiler, 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);
-        FunctionElement redirection =
-            resolver.resolveInitializers(element, tree);
-        if (redirection != null) {
-          resolveRedirectingConstructor(resolver, tree, element, redirection);
-        }
-      } else if (tree.initializers != null) {
-        error(tree, MessageKind.FUNCTION_WITH_INITIALIZER);
-      }
-
-      if (!compiler.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.
-        Iterable<MixinApplicationElement> mixinUses =
-            compiler.world.allMixinUsesOf(enclosingClass);
-        ClassElement mixin = enclosingClass;
-        for (MixinApplicationElement mixinApplication in mixinUses) {
-          checkMixinSuperUses(resolutionTree, mixinApplication, mixin);
-        }
-      }
-
-      // TODO(9631): support noSuchMethod on native classes.
-      if (Elements.isInstanceMethod(element) &&
-          element.name == Compiler.NO_SUCH_METHOD &&
-          _isNativeClassOrExtendsNativeClass(enclosingClass)) {
-        error(tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE);
-      }
-
-      return resolutionTree;
-    });
-
-  }
-
-  TreeElements resolveMethodElement(FunctionElementX element) {
-    assert(invariant(element, element.isDeclaration));
-    return compiler.withCurrentElement(element, () {
-      if (compiler.enqueuer.resolution.hasBeenResolved(element)) {
-        // TODO(karlklose): Remove the check for [isConstructor]. [elememts]
-        // should never be non-null, not even for constructors.
-        assert(invariant(element, element.isConstructor,
-            message: 'Non-constructor element $element '
-                     'has already been analyzed.'));
-        return element.resolvedAst.elements;
-      }
-      if (element.isSynthesized) {
-        if (element.isGenerativeConstructor) {
-          ResolutionRegistry registry =
-              new ResolutionRegistry(compiler, 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.
-          element.computeSignature(compiler);
-          if (!target.isErroneous) {
-            registry.registerStaticUse(target);
-            registry.registerImplicitSuperCall(target);
-          }
-          return registry.mapping;
-        } else {
-          assert(element.isDeferredLoaderGetter || element.isErroneous);
-          return _ensureTreeElements(element);
-        }
-      } else {
-        element.parseNode(compiler);
-        element.computeType(compiler);
-        FunctionElementX implementation = element;
-        if (element.isExternal) {
-          implementation = compiler.backend.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(compiler, element,
-        new ResolutionRegistry(compiler, element),
-        useEnclosingScope: useEnclosingScope);
-  }
-
-  TreeElements resolveField(FieldElementX element) {
-    VariableDefinitions tree = element.parseNode(compiler);
-    if(element.modifiers.isStatic && element.isTopLevel) {
-      error(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(tree.definitions.nodes.head, element);
-    // TODO(johnniwinther): Share the resolved type between all variables
-    // declared in the same declaration.
-    if (tree.type != null) {
-      element.variables.type = visitor.resolveTypeAnnotation(tree.type);
-    } else {
-      element.variables.type = const DynamicType();
-    }
-
-    Expression initializer = element.initializer;
-    Modifiers modifiers = element.modifiers;
-    if (initializer != null) {
-      // TODO(johnniwinther): Avoid analyzing initializers if
-      // [Compiler.analyzeSignaturesOnly] is set.
-      visitor.visit(initializer);
-    } else if (modifiers.isConst) {
-      compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER);
-    } else if (modifiers.isFinal && !element.isInstanceMember) {
-      compiler.reportError(element, MessageKind.FINAL_WITHOUT_INITIALIZER);
-    } else {
-      registry.registerInstantiatedClass(compiler.nullClass);
-    }
-
-    if (Elements.isStaticOrTopLevelField(element)) {
-      visitor.addDeferredAction(element, () {
-        if (element.modifiers.isConst) {
-          element.constant = constantCompiler.compileConstant(element);
-        } else {
-          constantCompiler.compileVariable(element);
-        }
-      });
-      if (initializer != null) {
-        if (!element.modifiers.isConst) {
-          // TODO(johnniwinther): Determine the const-ness eagerly to avoid
-          // unnecessary registrations.
-          registry.registerLazyField();
-        }
-      }
-    }
-
-    // Perform various checks as side effect of "computing" the type.
-    element.computeType(compiler);
-
-    return registry.mapping;
-  }
-
-  DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) {
-    DartType type = resolveReturnType(element, annotation);
-    if (type.isVoid) {
-      error(annotation, MessageKind.VOID_NOT_ALLOWED);
-    }
-    return type;
-  }
-
-  DartType resolveReturnType(Element element, TypeAnnotation annotation) {
-    if (annotation == null) return const DynamicType();
-    DartType result = visitorFor(element).resolveTypeAnnotation(annotation);
-    if (result == null) {
-      // TODO(karklose): warning.
-      return const DynamicType();
-    }
-    return result;
-  }
-
-  void resolveRedirectionChain(ConstructorElementX constructor,
-                               Spannable node) {
-    ConstructorElementX target = constructor;
-    InterfaceType targetType;
-    List<Element> seen = new List<Element>();
-    // Follow the chain of redirections and check for cycles.
-    while (target.isRedirectingFactory) {
-      if (target.internalEffectiveTarget != null) {
-        // We found a constructor that already has been processed.
-        targetType = target.effectiveTargetType;
-        assert(invariant(target, targetType != null,
-            message: 'Redirection target type has not been computed for '
-                     '$target'));
-        target = target.internalEffectiveTarget;
-        break;
-      }
-
-      Element nextTarget = target.immediateRedirectionTarget;
-      if (seen.contains(nextTarget)) {
-        error(node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
-        targetType = target.enclosingClass.thisType;
-        break;
-      }
-      seen.add(target);
-      target = nextTarget;
-    }
-
-    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();
-
-      // [factory] must already be analyzed but the [TreeElements] might not
-      // have been stored in the enqueuer cache yet.
-      // TODO(johnniwinther): Store [TreeElements] in the cache before
-      // resolution of the element.
-      TreeElements treeElements = factory.treeElements;
-      assert(invariant(node, treeElements != null,
-          message: 'No TreeElements cached for $factory.'));
-      FunctionExpression functionNode = factory.parseNode(compiler);
-      RedirectingFactoryBody redirectionNode = functionNode.body;
-      DartType factoryType = treeElements.getType(redirectionNode);
-      if (!factoryType.isDynamic) {
-        targetType = targetType.substByContext(factoryType);
-      }
-      factory.effectiveTarget = target;
-      factory.effectiveTargetType = targetType;
-    }
-  }
-
-  /**
-   * 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) {
-    compiler.withCurrentElement(cls, () => measure(() {
-      if (cls.supertypeLoadState == STATE_DONE) return;
-      if (cls.supertypeLoadState == STATE_STARTED) {
-        compiler.reportError(from, MessageKind.CYCLIC_CLASS_HIERARCHY,
-                                 {'className': cls.name});
-        cls.supertypeLoadState = STATE_DONE;
-        cls.hasIncompleteHierarchy = true;
-        cls.allSupertypesAndSelf =
-            compiler.objectClass.allSupertypesAndSelf.extendClass(
-                cls.computeType(compiler));
-        cls.supertype = cls.allSupertypes.head;
-        assert(invariant(from, cls.supertype != null,
-            message: 'Missing supertype on cyclic class $cls.'));
-        cls.interfaces = const Link<DartType>();
-        return;
-      }
-      cls.supertypeLoadState = STATE_STARTED;
-      compiler.withCurrentElement(cls, () {
-        // TODO(ahe): Cache the node in cls.
-        cls.parseNode(compiler).accept(
-            new ClassSupertypeResolver(compiler, 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.
-  TypeDeclarationElement currentlyResolvedTypeDeclaration;
-  Queue<ClassElement> pendingClassesToBeResolved = new Queue<ClassElement>();
-  Queue<ClassElement> pendingClassesToBePostProcessed =
-      new Queue<ClassElement>();
-
-  /// Resolve [element] using [resolveTypeDeclaration].
-  ///
-  /// This methods ensure 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 compiler.withCurrentElement(element, () {
-      return measure(() {
-        TypeDeclarationElement previousResolvedTypeDeclaration =
-            currentlyResolvedTypeDeclaration;
-        currentlyResolvedTypeDeclaration = element;
-        var result = resolveTypeDeclaration();
-        if (previousResolvedTypeDeclaration == null) {
-          do {
-            while (!pendingClassesToBeResolved.isEmpty) {
-              pendingClassesToBeResolved.removeFirst().ensureResolved(compiler);
-            }
-            while (!pendingClassesToBePostProcessed.isEmpty) {
-              _postProcessClassElement(
-                  pendingClassesToBePostProcessed.removeFirst());
-            }
-          } while (!pendingClassesToBeResolved.isEmpty);
-          assert(pendingClassesToBeResolved.isEmpty);
-          assert(pendingClassesToBePostProcessed.isEmpty);
-        }
-        currentlyResolvedTypeDeclaration = previousResolvedTypeDeclaration;
-        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(compiler):].
-   */
-  TreeElements resolveClass(BaseClassElementX element) {
-    return _resolveTypeDeclaration(element, () {
-      // TODO(johnniwinther): Store the mapping in the resolution enqueuer.
-      ResolutionRegistry registry = new ResolutionRegistry(compiler, element);
-      resolveClassInternal(element, registry);
-      return element.treeElements;
-    });
-  }
-
-  void _ensureClassWillBeResolved(ClassElement element) {
-    if (currentlyResolvedTypeDeclaration == null) {
-      element.ensureResolved(compiler);
-    } else {
-      pendingClassesToBeResolved.add(element);
-    }
-  }
-
-  void resolveClassInternal(BaseClassElementX element,
-                            ResolutionRegistry registry) {
-    if (!element.isPatch) {
-      compiler.withCurrentElement(element, () => measure(() {
-        assert(element.resolutionState == STATE_NOT_STARTED);
-        element.resolutionState = STATE_STARTED;
-        Node tree = element.parseNode(compiler);
-        loadSupertypes(element, tree);
-
-        ClassResolverVisitor visitor =
-            new ClassResolverVisitor(compiler, element, registry);
-        visitor.visit(tree);
-        element.resolutionState = STATE_DONE;
-        compiler.onClassResolved(element);
-        pendingClassesToBePostProcessed.add(element);
-      }));
-      if (element.isPatched) {
-        // Ensure handling patch after origin.
-        element.patch.ensureResolved(compiler);
-      }
-    } else { // Handle patch classes:
-      element.resolutionState = STATE_STARTED;
-      // Ensure handling origin before patch.
-      element.origin.ensureResolved(compiler);
-      // Ensure that the type is computed.
-      element.computeType(compiler);
-      // 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.metadata) {
-      metadata.ensureResolved(compiler);
-      if (!element.isProxy &&
-          metadata.constant.value == compiler.proxyConstant) {
-        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) {
-        compiler.withCurrentElement(member, () {
-          for (MetadataAnnotation metadata in member.metadata) {
-            metadata.ensureResolved(compiler);
-          }
-        });
-      }
-    });
-
-    computeClassMember(element, Compiler.CALL_OPERATOR_NAME);
-  }
-
-  void computeClassMembers(ClassElement element) {
-    MembersCreator.computeAllClassMembers(compiler, element);
-  }
-
-  void computeClassMember(ClassElement element, String name) {
-    MembersCreator.computeClassMembersByName(compiler, 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);
-      compiler.reportError(
-          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) {
-      compiler.reportError(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) {
-      compiler.reportError(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((AstElement member) {
-      if (member.isGenerativeConstructor && !member.isSynthesized) {
-        compiler.reportError(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 (compiler.enqueuer.resolution.hasBeenResolved(member)) {
-          checkMixinSuperUses(
-              member.resolvedAst.elements,
-              mixinApplication,
-              mixin);
-        }
-      }
-    });
-  }
-
-  void checkMixinSuperUses(TreeElements resolutionTree,
-                           MixinApplicationElement mixinApplication,
-                           ClassElement mixin) {
-    // TODO(johnniwinther): Avoid the use of [TreeElements] here.
-    if (resolutionTree == null) return;
-    Iterable<Node> superUses = resolutionTree.superUses;
-    if (superUses.isEmpty) return;
-    compiler.reportError(mixinApplication,
-                         MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
-                         {'className': mixin.name});
-    // Show the user the problematic uses of 'super' in the mixin.
-    for (Node use in superUses) {
-      compiler.reportInfo(
-          use,
-          MessageKind.ILLEGAL_MIXIN_SUPER_USE);
-    }
-  }
-
-  void checkClassMembers(ClassElement cls) {
-    assert(invariant(cls, cls.isDeclaration));
-    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, member) {
-      compiler.withCurrentElement(member, () {
-        // Perform various checks as side effect of "computing" the type.
-        member.computeType(compiler);
-
-        // Check modifiers.
-        if (member.isFunction && member.modifiers.isFinal) {
-          compiler.reportError(
-              member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
-        }
-        if (member.isConstructor) {
-          final mismatchedFlagsBits =
-              member.modifiers.flags &
-              (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT);
-          if (mismatchedFlagsBits != 0) {
-            final mismatchedFlags =
-                new Modifiers.withFlags(null, mismatchedFlagsBits);
-            compiler.reportError(
-                member,
-                MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
-                {'modifiers': mismatchedFlags});
-          }
-          if (member.modifiers.isConst) {
-            constConstructors.add(member);
-          }
-        }
-        if (member.isField) {
-          if (member.modifiers.isConst && !member.modifiers.isStatic) {
-            compiler.reportError(
-                member, MessageKind.ILLEGAL_CONST_FIELD_MODIFIER);
-          }
-          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];
-      compiler.reportError(span,
-          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
-          {'className': cls.name});
-      if (constConstructors.length > 1) {
-        for (Element constructor in constConstructors) {
-          compiler.reportInfo(constructor,
-              MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR);
-        }
-      }
-      for (Element field in nonFinalInstanceFields) {
-        compiler.reportInfo(field,
-            MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD);
-      }
-    }
-  }
-
-  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) {
-      compiler.internalError(member,
-          "No abstract field for accessor");
-    } else if (!identical(lookupElement.kind, ElementKind.ABSTRACT_FIELD)) {
-      if (lookupElement.isErroneous || lookupElement.isAmbiguous) return;
-      compiler.internalError(member,
-          "Inaccessible abstract field for accessor");
-    }
-    AbstractFieldElement field = lookupElement;
-
-    MethodElementX getter = field.getter;
-    if (getter == null) return;
-    MethodElementX setter = field.setter;
-    if (setter == null) return;
-    int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
-    int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
-    if (!identical(getterFlags, setterFlags)) {
-      final mismatchedFlags =
-        new Modifiers.withFlags(null, getterFlags ^ setterFlags);
-      compiler.reportError(
-          field.getter,
-          MessageKind.GETTER_MISMATCH,
-          {'modifiers': mismatchedFlags});
-      compiler.reportError(
-          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 {
-      compiler.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;
-    compiler.reportHint(
-        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;
-        }
-      }
-      compiler.reportError(
-          errorNode, messageKind, {'operatorName': function.name});
-    }
-    if (signature.optionalParameterCount != 0) {
-      Node errorNode =
-          node.parameters.nodes.skip(signature.requiredParameterCount).head;
-      if (signature.optionalParametersAreNamed) {
-        compiler.reportError(
-            errorNode,
-            MessageKind.OPERATOR_NAMED_PARAMETERS,
-            {'operatorName': function.name});
-      } else {
-        compiler.reportError(
-            errorNode,
-            MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
-            {'operatorName': function.name});
-      }
-    }
-  }
-
-  reportErrorWithContext(Element errorneousElement,
-                         MessageKind errorMessage,
-                         Element contextElement,
-                         MessageKind contextMessage) {
-    compiler.reportError(
-        errorneousElement,
-        errorMessage,
-        {'memberName': contextElement.name,
-         'className': contextElement.enclosingClass.name});
-    compiler.reportInfo(contextElement, contextMessage);
-  }
-
-
-  FunctionSignature resolveSignature(FunctionElementX element) {
-    MessageKind defaultValuesError = null;
-    if (element.isFactoryConstructor) {
-      FunctionExpression body = element.parseNode(compiler);
-      if (body.isRedirectingFactory) {
-        defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT;
-      }
-    }
-    return compiler.withCurrentElement(element, () {
-      FunctionExpression node =
-          compiler.parser.measure(() => element.parseNode(compiler));
-      return measure(() => SignatureResolver.analyze(
-          compiler, node.parameters, node.returnType, element,
-          new ResolutionRegistry(compiler, element),
-          defaultValuesError: defaultValuesError,
-          createRealParameters: true));
-    });
-  }
-
-  TreeElements resolveTypedef(TypedefElementX element) {
-    if (element.isResolved) return element.treeElements;
-    compiler.world.allTypedefs.add(element);
-    return _resolveTypeDeclaration(element, () {
-      ResolutionRegistry registry = new ResolutionRegistry(compiler, element);
-      return compiler.withCurrentElement(element, () {
-        return measure(() {
-          assert(element.resolutionState == STATE_NOT_STARTED);
-          element.resolutionState = STATE_STARTED;
-          Typedef node =
-            compiler.parser.measure(() => element.parseNode(compiler));
-          TypedefResolverVisitor visitor =
-            new TypedefResolverVisitor(compiler, element, registry);
-          visitor.visit(node);
-          element.resolutionState = STATE_DONE;
-          return registry.mapping;
-        });
-      });
-    });
-  }
-
-  void resolveMetadataAnnotation(MetadataAnnotationX annotation) {
-    compiler.withCurrentElement(annotation.annotatedElement, () => measure(() {
-      assert(annotation.resolutionState == STATE_NOT_STARTED);
-      annotation.resolutionState = STATE_STARTED;
-
-      Node node = annotation.parseNode(compiler);
-      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(compiler);
-      }
-      assert(invariant(node, context != null,
-          message: "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].
-      annotation.constant =
-          constantCompiler.compileMetadata(annotation, node, registry.mapping);
-      // 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).
-      registry.registerMetadataConstant(annotation, annotatedElement);
-      annotation.resolutionState = STATE_DONE;
-    }));
-  }
-
-  error(Spannable node, MessageKind kind, [arguments = const {}]) {
-    compiler.reportError(node, kind, arguments);
-  }
-
-  Link<MetadataAnnotation> resolveMetadata(Element element,
-                                           VariableDefinitions node) {
-    LinkBuilder<MetadataAnnotation> metadata =
-        new LinkBuilder<MetadataAnnotation>();
-    for (Metadata annotation in node.metadata.nodes) {
-      ParameterMetadataAnnotation metadataAnnotation =
-          new ParameterMetadataAnnotation(annotation);
-      metadataAnnotation.annotatedElement = element;
-      metadata.addLast(metadataAnnotation.ensureResolved(compiler));
-    }
-    return metadata.toLink();
-  }
-}
-
-class InitializerResolver {
-  final ResolverVisitor visitor;
-  final Map<Element, Node> initialized;
-  Link<Node> initializers;
-  bool hasSuper;
-
-  InitializerResolver(this.visitor)
-    : initialized = new Map<Element, Node>(), hasSuper = false;
-
-  ResolutionRegistry get registry => visitor.registry;
-
-  error(Node node, MessageKind kind, [arguments = const {}]) {
-    visitor.error(node, kind, arguments);
-  }
-
-  warning(Node node, MessageKind kind, [arguments = const {}]) {
-    visitor.warning(node, kind, arguments);
-  }
-
-  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, Node existing) {
-    visitor.compiler.reportError(
-        init,
-        MessageKind.DUPLICATE_INITIALIZER, {'fieldName': field.name});
-    visitor.compiler.reportInfo(
-        existing,
-        MessageKind.ALREADY_INITIALIZED, {'fieldName': field.name});
-  }
-
-  void checkForDuplicateInitializers(FieldElementX field, Node init) {
-    // [field] can be null if it could not be resolved.
-    if (field == null) return;
-    String name = field.name;
-    if (initialized.containsKey(field)) {
-      reportDuplicateInitializerError(field, init, initialized[field]);
-    } else if (field.isFinal) {
-      field.parseNode(visitor.compiler);
-      Expression initializer = field.initializer;
-      if (initializer != null) {
-        reportDuplicateInitializerError(field, init, initializer);
-      }
-    }
-    initialized[field] = init;
-  }
-
-  void resolveFieldInitializer(FunctionElement constructor, 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;
-    if (isFieldInitializer(init)) {
-      target = constructor.enclosingClass.lookupLocalMember(name);
-      if (target == null) {
-        error(selector, MessageKind.CANNOT_RESOLVE, {'name': name});
-        target = new ErroneousFieldElementX(
-            selector.asIdentifier(), constructor.enclosingClass);
-      } else if (target.kind != ElementKind.FIELD) {
-        error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name});
-        target = new ErroneousFieldElementX(
-            selector.asIdentifier(), constructor.enclosingClass);
-      } else if (!target.isInstanceMember) {
-        error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name});
-      }
-    } else {
-      error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
-    }
-    registry.useElement(init, target);
-    registry.registerStaticUse(target);
-    checkForDuplicateInitializers(target, init);
-    // Resolve initializing value.
-    visitor.visitInStaticContext(init.arguments.head);
-  }
-
-  ClassElement getSuperOrThisLookupTarget(FunctionElement constructor,
-                                          bool isSuperCall,
-                                          Node diagnosticNode) {
-    ClassElement lookupTarget = constructor.enclosingClass;
-    if (isSuperCall) {
-      // Calculate correct lookup target and constructor name.
-      if (identical(lookupTarget, visitor.compiler.objectClass)) {
-        error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
-      } else {
-        return lookupTarget.supertype.element;
-      }
-    }
-    return lookupTarget;
-  }
-
-  Element resolveSuperOrThisForSend(FunctionElement constructor,
-                                    FunctionExpression functionNode,
-                                    Send call) {
-    // Resolve the selector and the arguments.
-    ResolverTask resolver = visitor.compiler.resolver;
-    visitor.inStaticContext(() {
-      visitor.resolveSelector(call, null);
-      visitor.resolveArguments(call.argumentsNode);
-    });
-    Selector selector = registry.getSelector(call);
-    bool isSuperCall = Initializers.isSuperConstructorCall(call);
-
-    ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
-                                                           isSuperCall,
-                                                           call);
-    Selector constructorSelector =
-        visitor.getRedirectingThisOrSuperConstructorSelector(call);
-    FunctionElement calledConstructor =
-        lookupTarget.lookupConstructor(constructorSelector.name);
-
-    final bool isImplicitSuperCall = false;
-    final String className = lookupTarget.name;
-    verifyThatConstructorMatchesCall(constructor,
-                                     calledConstructor,
-                                     selector.callStructure,
-                                     isImplicitSuperCall,
-                                     call,
-                                     className,
-                                     constructorSelector);
-
-    registry.useElement(call, calledConstructor);
-    registry.registerStaticUse(calledConstructor);
-    return calledConstructor;
-  }
-
-  void resolveImplicitSuperConstructorSend(FunctionElement constructor,
-                                           FunctionExpression functionNode) {
-    // If the class has a super resolve the implicit super call.
-    ClassElement classElement = constructor.enclosingClass;
-    ClassElement superClass = classElement.superclass;
-    if (classElement != visitor.compiler.objectClass) {
-      assert(superClass != null);
-      assert(superClass.resolutionState == STATE_DONE);
-
-      final bool isSuperCall = true;
-      ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
-                                                             isSuperCall,
-                                                             functionNode);
-      Selector constructorSelector = new Selector.callDefaultConstructor();
-      Element calledConstructor = lookupTarget.lookupConstructor(
-          constructorSelector.name);
-
-      final String className = lookupTarget.name;
-      final bool isImplicitSuperCall = true;
-      verifyThatConstructorMatchesCall(constructor,
-                                       calledConstructor,
-                                       CallStructure.NO_ARGS,
-                                       isImplicitSuperCall,
-                                       functionNode,
-                                       className,
-                                       constructorSelector);
-      registry.registerImplicitSuperCall(calledConstructor);
-      registry.registerStaticUse(calledConstructor);
-    }
-  }
-
-  void verifyThatConstructorMatchesCall(
-      FunctionElement caller,
-      ConstructorElementX lookedupConstructor,
-      CallStructure call,
-      bool isImplicitSuperCall,
-      Node diagnosticNode,
-      String className,
-      Selector constructorSelector) {
-    if (lookedupConstructor == null
-        || !lookedupConstructor.isGenerativeConstructor) {
-      String fullConstructorName = Elements.constructorNameForDiagnostics(
-              className,
-              constructorSelector.name);
-      MessageKind kind = isImplicitSuperCall
-          ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
-          : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
-      visitor.compiler.reportError(
-          diagnosticNode, kind, {'constructorName': fullConstructorName});
-    } else {
-      lookedupConstructor.computeSignature(visitor.compiler);
-      if (!call.signatureApplies(lookedupConstructor)) {
-        MessageKind kind = isImplicitSuperCall
-                           ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
-                           : MessageKind.NO_MATCHING_CONSTRUCTOR;
-        visitor.compiler.reportError(diagnosticNode, kind);
-      } else if (caller.isConst
-                 && !lookedupConstructor.isConst) {
-        visitor.compiler.reportError(
-            diagnosticNode, MessageKind.CONST_CALLS_NON_CONST);
-      }
-    }
-  }
-
-  /**
-   * Resolve all initializers of this constructor. In the case of a redirecting
-   * constructor, the resolved constructor's function element is returned.
-   */
-  ConstructorElement resolveInitializers(ConstructorElementX constructor,
-                                         FunctionExpression functionNode) {
-    // 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;
-    functionParameters.forEachParameter((ParameterElement element) {
-      if (element.isInitializingFormal) {
-        InitializingFormalElement initializingFormal = element;
-        checkForDuplicateInitializers(initializingFormal.fieldElement,
-                                      element.initializer);
-      }
-    });
-
-    if (functionNode.initializers == null) {
-      initializers = const Link<Node>();
-    } else {
-      initializers = functionNode.initializers.nodes;
-    }
-    FunctionElement result;
-    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(constructor, init);
-      } else if (link.head.asSend() != null) {
-        final Send call = link.head.asSend();
-        if (call.argumentsNode == null) {
-          error(link.head, MessageKind.INVALID_INITIALIZER);
-          continue;
-        }
-        if (Initializers.isSuperConstructorCall(call)) {
-          if (resolvedSuper) {
-            error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER);
-          }
-          resolveSuperOrThisForSend(constructor, functionNode, call);
-          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) {
-            error(functionNode, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY);
-          }
-          // Check that there are no other initializers.
-          if (!initializers.tail.isEmpty) {
-            error(call, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER);
-          } else {
-            constructor.isRedirectingGenerative = true;
-          }
-          // Check that there are no field initializing parameters.
-          Compiler compiler = visitor.compiler;
-          FunctionSignature signature = constructor.functionSignature;
-          signature.forEachParameter((ParameterElement parameter) {
-            if (parameter.isInitializingFormal) {
-              Node node = parameter.node;
-              error(node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED);
-            }
-          });
-          return resolveSuperOrThisForSend(constructor, functionNode, call);
-        } else {
-          visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED);
-          return null;
-        }
-      } else {
-        error(link.head, MessageKind.INVALID_INITIALIZER);
-      }
-    }
-    if (!resolvedSuper) {
-      resolveImplicitSuperConstructorSend(constructor, functionNode);
-    }
-    return null;  // If there was no redirection always return null.
-  }
-}
-
-class CommonResolverVisitor<R> extends Visitor<R> {
-  final Compiler compiler;
-
-  CommonResolverVisitor(Compiler this.compiler);
-
-  R visitNode(Node node) {
-    internalError(node,
-        'internal error: Unhandled node: ${node.getObjectDescription()}');
-    return null;
-  }
-
-  R visitEmptyStatement(Node node) => null;
-
-  /** Convenience method for visiting nodes that may be null. */
-  R visit(Node node) => (node == null) ? null : node.accept(this);
-
-  void error(Spannable node, MessageKind kind, [Map arguments = const {}]) {
-    compiler.reportError(node, kind, arguments);
-  }
-
-  void warning(Spannable node, MessageKind kind, [Map arguments = const {}]) {
-    compiler.reportWarning(node, kind, arguments);
-  }
-
-  void internalError(Spannable node, message) {
-    compiler.internalError(node, message);
-  }
-
-  void addDeferredAction(Element element, DeferredAction action) {
-    compiler.enqueuer.resolution.addDeferredAction(element, action);
-  }
-}
-
-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;
-  }
-}
-
-class TypeResolver {
-  final Compiler compiler;
-
-  TypeResolver(this.compiler);
-
-  /// Tries to resolve the type name as an element.
-  Element resolveTypeName(Identifier prefixName,
-                          Identifier typeName,
-                          Scope scope,
-                          {bool deferredIsMalformed: true}) {
-    Element element;
-    bool deferredTypeAnnotation = false;
-    if (prefixName != null) {
-      Element prefixElement =
-          lookupInScope(compiler, 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);
-        // TODO(17260, sigurdm): The test for DartBackend is there because
-        // dart2dart outputs malformed types with prefix.
-        if (element != null &&
-            prefix.isDeferred &&
-            deferredIsMalformed &&
-            compiler.backend is! DartBackend) {
-          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 {
-      String stringValue = typeName.source;
-      element = lookupInScope(compiler, typeName, scope, typeName.source);
-    }
-    return element;
-  }
-
-  DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node,
-                                 {bool malformedIsError: false,
-                                  bool deferredIsMalformed: true}) {
-    ResolutionRegistry registry = visitor.registry;
-
-    Identifier typeName;
-    DartType type;
-
-    DartType checkNoTypeArguments(DartType type) {
-      List<DartType> arguments = new List<DartType>();
-      bool hasTypeArgumentMismatch = resolveTypeArguments(
-          visitor, node, const <DartType>[], arguments);
-      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 VoidType();
-        checkNoTypeArguments(type);
-        registry.useType(node, type);
-        return type;
-      } else if (identical(typeName.source, 'dynamic')) {
-        type = const DynamicType();
-        checkNoTypeArguments(type);
-        registry.useType(node, type);
-        return type;
-      }
-    }
-
-    Element element = resolveTypeName(prefixName, typeName, visitor.scope,
-                                      deferredIsMalformed: deferredIsMalformed);
-
-    DartType reportFailureAndCreateType(MessageKind messageKind,
-                                        Map messageArguments,
-                                        {DartType userProvidedBadType,
-                                         Element erroneousElement}) {
-      if (malformedIsError) {
-        visitor.error(node, messageKind, messageArguments);
-      } else {
-        registry.registerThrowRuntimeError();
-        visitor.warning(node, messageKind, messageArguments);
-      }
-      if (erroneousElement == null) {
-        registry.registerThrowRuntimeError();
-        erroneousElement = new ErroneousElementX(
-            messageKind, messageArguments, typeName.source,
-            visitor.enclosingElement);
-      }
-      List<DartType> arguments = <DartType>[];
-      resolveTypeArguments(visitor, node, const <DartType>[], arguments);
-      return new MalformedType(erroneousElement,
-              userProvidedBadType, arguments);
-    }
-
-    // Try to construct the type from the element.
-    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);
-      ambiguous.diagnose(registry.mapping.analyzedElement, compiler);
-    } else if (element.isErroneous) {
-      if (element is ErroneousElement) {
-        type = reportFailureAndCreateType(
-            element.messageKind, element.messageArguments,
-            erroneousElement: element);
-      } else {
-        type = const DynamicType();
-      }
-    } else if (!element.impliesType) {
-      type = reportFailureAndCreateType(
-          MessageKind.NOT_A_TYPE, {'node': node.typeName});
-    } else {
-      bool addTypeVariableBoundsCheck = false;
-      if (element.isClass) {
-        ClassElement cls = element;
-        // TODO(johnniwinther): [_ensureClassWillBeResolved] should imply
-        // [computeType].
-        compiler.resolver._ensureClassWillBeResolved(cls);
-        element.computeType(compiler);
-        List<DartType> arguments = <DartType>[];
-        bool hasTypeArgumentMismatch = resolveTypeArguments(
-            visitor, node, cls.typeVariables, arguments);
-        if (hasTypeArgumentMismatch) {
-          type = new BadInterfaceType(cls.declaration,
-              new InterfaceType.forUserProvidedBadType(cls.declaration,
-                                                       arguments));
-        } else {
-          if (arguments.isEmpty) {
-            type = cls.rawType;
-          } else {
-            type = new InterfaceType(cls.declaration, arguments.toList(growable: false));
-            addTypeVariableBoundsCheck = true;
-          }
-        }
-      } else if (element.isTypedef) {
-        TypedefElement typdef = element;
-        // TODO(johnniwinther): [ensureResolved] should imply [computeType].
-        typdef.ensureResolved(compiler);
-        element.computeType(compiler);
-        List<DartType> arguments = <DartType>[];
-        bool hasTypeArgumentMismatch = resolveTypeArguments(
-            visitor, node, typdef.typeVariables, arguments);
-        if (hasTypeArgumentMismatch) {
-          type = new BadTypedefType(typdef,
-              new TypedefType.forUserProvidedBadType(typdef, arguments));
-        } else {
-          if (arguments.isEmpty) {
-            type = typdef.rawType;
-          } else {
-            type = new TypedefType(typdef, arguments.toList(growable: false));
-            addTypeVariableBoundsCheck = true;
-          }
-        }
-      } else if (element.isTypeVariable) {
-        Element outer =
-            visitor.enclosingElement.outermostEnclosingMemberOrTopLevel;
-        bool isInFactoryConstructor =
-            outer != null && outer.isFactoryConstructor;
-        if (!outer.isClass &&
-            !outer.isTypedef &&
-            !Elements.hasAccessToTypeVariables(visitor.enclosingElement)) {
-          registry.registerThrowRuntimeError();
-          type = reportFailureAndCreateType(
-              MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
-              {'typeVariableName': node},
-              userProvidedBadType: element.computeType(compiler));
-        } else {
-          type = element.computeType(compiler);
-        }
-        type = checkNoTypeArguments(type);
-      } else {
-        compiler.internalError(node,
-            "Unexpected element kind ${element.kind}.");
-      }
-      if (addTypeVariableBoundsCheck) {
-        registry.registerTypeVariableBoundCheck();
-        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(TypeAnnotation node, GenericType type) {
-    void checkTypeVariableBound(_, DartType typeArgument,
-                                   TypeVariableType typeVariable,
-                                   DartType bound) {
-      if (!compiler.types.isSubtype(typeArgument, bound)) {
-        compiler.reportWarning(node,
-            MessageKind.INVALID_TYPE_VARIABLE_BOUND,
-            {'typeVariable': typeVariable,
-             'bound': bound,
-             'typeArgument': typeArgument,
-             'thisType': type.element.thisType});
-      }
-    };
-
-    compiler.types.checkTypeVariableBounds(type, 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,
-                            TypeAnnotation node,
-                            List<DartType> typeVariables,
-                            List<DartType> arguments) {
-    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) {
-        visitor.warning(
-            typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
-        typeArgumentCountMismatch = true;
-      }
-      DartType argType = resolveTypeAnnotation(visitor, typeArguments.head);
-      // TODO(karlklose): rewrite to not modify [arguments].
-      arguments.add(argType);
-    }
-    if (index < expectedVariables) {
-      visitor.warning(node.typeArguments,
-                      MessageKind.MISSING_TYPE_ARGUMENT);
-      typeArgumentCountMismatch = true;
-    }
-    return typeArgumentCountMismatch;
-  }
-}
-
-/**
- * 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(Compiler compiler, ResolutionRegistry this.registry)
-      : typeResolver = new TypeResolver(compiler),
-        super(compiler);
-
-  AsyncMarker get currentAsyncMarker => AsyncMarker.SYNC;
-
-  /// Add [element] to the current scope and check for duplicate definitions.
-  void addToScope(Element element) {
-    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') {
-        compiler.reportError(
-            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 compiler.internalError(node, 'element is null');
-    }
-    checkLocalDefinitionName(node, element);
-    registry.defineElement(node, element);
-  }
-
-  void reportDuplicateDefinition(String name,
-                                 Spannable definition,
-                                 Spannable existing) {
-    compiler.reportError(definition,
-        MessageKind.DUPLICATE_DEFINITION, {'name': name});
-    compiler.reportInfo(existing,
-        MessageKind.EXISTING_DEFINITION, {'name': name});
-  }
-}
-
 /**
  * Core implementation of resolution.
  *
@@ -2407,8 +313,8 @@
     functionParameters.forEachParameter((ParameterElement element) {
       // TODO(karlklose): should be a list of [FormalElement]s, but the actual
       // implementation uses [Element].
-      Link<Element> optionals = functionParameters.optionalParameters;
-      if (!optionals.isEmpty && element == optionals.head) {
+      List<Element> optionals = functionParameters.optionalParameters;
+      if (!optionals.isEmpty && element == optionals.first) {
         NodeList nodes = parameterNodes.head;
         parameterNodes = nodes.nodes;
       }
@@ -2579,16 +485,20 @@
       // If this send is of the form "assert(expr);", then
       // this is an assertion.
       if (selector.isAssert) {
+        SendStructure sendStructure = const AssertStructure();
         if (selector.argumentCount != 1) {
           error(node.selector,
                 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT,
                 {'argumentCount': selector.argumentCount});
+          sendStructure = const InvalidAssertStructure();
         } else if (selector.namedArgumentCount != 0) {
           error(node.selector,
                 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS,
                 {'argumentCount': selector.namedArgumentCount});
+          sendStructure = const InvalidAssertStructure();
         }
         registry.registerAssert(node);
+        registry.registerSendStructure(node, sendStructure);
         return const AssertResult();
       }
 
@@ -2597,7 +507,26 @@
 
     var oldCategory = allowedCategory;
     allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER;
+
+    bool oldSendIsMemberAccess = sendIsMemberAccess;
+    int oldAllowedCategory = allowedCategory;
+
+    // Conditional sends like `e?.foo` treat the receiver as an expression.  So
+    // `C?.foo` needs to be treated like `(C).foo`, not like C.foo. Prefixes and
+    // super are not allowed on their own in that context.
+    if (node.isConditional) {
+      sendIsMemberAccess = false;
+      allowedCategory =
+          ElementCategory.VARIABLE |
+          ElementCategory.FUNCTION |
+          ElementCategory.IMPLIES_TYPE;
+    }
     ResolutionResult resolvedReceiver = visit(node.receiver);
+    if (node.isConditional) {
+      sendIsMemberAccess = oldSendIsMemberAccess;
+      allowedCategory = oldAllowedCategory;
+    }
+
     allowedCategory = oldCategory;
 
     Element target;
@@ -2629,13 +558,13 @@
       }
       // TODO(johnniwinther): Ensure correct behavior if currentClass is a
       // patch.
-      target = currentClass.lookupSuperSelector(selector);
+      target = currentClass.lookupSuperByName(selector.memberName);
       // [target] may be null which means invoking noSuchMethod on
       // super.
       if (target == null) {
         target = reportAndCreateErroneousElement(
             node, name, MessageKind.NO_SUCH_SUPER_MEMBER,
-            {'className': currentClass, 'memberName': name});
+            {'className': currentClass.name, 'memberName': name});
         // We still need to register the invocation, because we might
         // call [:super.noSuchMethod:] which calls
         // [JSInvocationMirror._invokeOn].
@@ -2722,7 +651,7 @@
       if (identical(string, '!') ||
           identical(string, '&&') || identical(string, '||') ||
           identical(string, 'is') || identical(string, 'as') ||
-          identical(string, '?') ||
+          identical(string, '?') || identical(string, '??') ||
           identical(string, '>>>')) {
         return null;
       }
@@ -2806,15 +735,382 @@
     sendIsMemberAccess = oldSendIsMemberAccess;
   }
 
+  void registerTypeLiteralAccess(Send node, Element target) {
+    // Set the type of the node to [Type] to mark this send as a
+    // type literal.
+    DartType type;
+
+    // TODO(johnniwinther): Remove this hack when we can pass more complex
+    // information between methods than resolved elements.
+    if (target == compiler.typeClass && node.receiver == null) {
+      // Potentially a 'dynamic' type literal.
+      type = registry.getType(node.selector);
+    }
+    if (type == null) {
+      type = target.computeType(compiler);
+    }
+    registry.registerTypeLiteral(node, type);
+
+    if (!target.isTypeVariable) {
+      // Don't try to make constants of calls and assignments to type literals.
+      if (!node.isCall && node.asSendSet() == null) {
+        analyzeConstantDeferred(node, enforceConst: false);
+      } else {
+        // The node itself is not a constant but we register the selector (the
+        // identifier that refers to the class/typedef) as a constant.
+        if (node.receiver != null) {
+          // This is a hack for the case of prefix.Type, we need to store
+          // the element on the selector, so [analyzeConstant] can build
+          // the type literal from the selector.
+          registry.useElement(node.selector, target);
+        }
+        analyzeConstantDeferred(node.selector, enforceConst: false);
+      }
+    }
+  }
+
+  /// Check that access to `super` is currently allowed.
+  bool checkSuperAccess(Node node) {
+    if (!inInstanceContext) {
+      compiler.reportError(node, MessageKind.NO_SUPER_AVAILABLE);
+      return false;
+    }
+    if (currentClass.supertype == null) {
+      // This is just to guard against internal errors, so no need
+      // for a real error message.
+      compiler.reportError(node, MessageKind.GENERIC,
+            {'text': "Object has no superclass"});
+      return false;
+    }
+    registry.registerSuperUse(node);
+    return true;
+  }
+
+  /// Compute the [AccessSemantics] corresponding to a super access of [target].
+  AccessSemantics computeSuperAccess(Spannable node, Element target) {
+    if (target.isErroneous) {
+      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) {
+      return new StaticAccess.superField(target);
+    } else {
+      assert(invariant(node, target.isFunction,
+          message: "Unexpected super target '$target'."));
+      return new StaticAccess.superMethod(target);
+    }
+  }
+
+  AccessSemantics computeSuperSemantics(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) {
+      Element error = reportAndCreateErroneousElement(
+          node, name.text, MessageKind.NO_SUCH_SUPER_MEMBER,
+          {'className': currentClass.name, 'memberName': name});
+      if (alternateName != null) {
+        target = currentClass.lookupSuperByName(alternateName);
+      }
+      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.registerDynamicInvocation(selector);
+      registry.registerSuperNoSuchMethod();
+    }
+    return computeSuperAccess(node, target);
+  }
+
+  ResolutionResult visitExpression(Node node) {
+    bool oldSendIsMemberAccess = sendIsMemberAccess;
+    sendIsMemberAccess = false;
+    ResolutionResult result = visit(node);
+    sendIsMemberAccess = oldSendIsMemberAccess;
+    return result;
+  }
+
+  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();
+    DartType type;
+    SendStructure sendStructure;
+    if (notTypeNode != null) {
+      // `e is! T`.
+      Node typeNode = notTypeNode.receiver;
+      type = resolveTypeAnnotation(typeNode);
+      sendStructure = new IsNotStructure(type);
+    } else {
+      // `e is T`.
+      Node typeNode = node.arguments.head;
+      type = resolveTypeAnnotation(typeNode);
+      sendStructure = new IsStructure(type);
+    }
+    registry.registerIsCheck(type);
+    registry.registerSendStructure(node, sendStructure);
+    return null;
+  }
+
+  ResolutionResult handleAs(Send node) {
+    Node expression = node.receiver;
+    visitExpression(expression);
+
+    Node typeNode = node.arguments.head;
+    DartType type = resolveTypeAnnotation(typeNode);
+    registry.registerAsCheck(type);
+    registry.registerSendStructure(node, new AsStructure(type));
+    return null;
+  }
+
+  ResolutionResult handleUnresolvedUnary(Send node, String text) {
+    Node expression = node.receiver;
+    if (node.isSuperCall) {
+      checkSuperAccess(node);
+    } else {
+      visitExpression(expression);
+    }
+
+    registry.registerSendStructure(node, const InvalidUnaryStructure());
+    return null;
+  }
+
+  ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) {
+    Node expression = node.receiver;
+    Selector selector = operator.selector;
+    // TODO(johnniwinther): Remove this when all information goes through the
+    // [SendStructure].
+    registry.setSelector(node, selector);
+
+    AccessSemantics semantics;
+    if (node.isSuperCall) {
+      if (checkSuperAccess(node)) {
+        semantics = computeSuperSemantics(node, selector);
+        // TODO(johnniwinther): Add information to [AccessSemantics] about
+        // whether it is erroneous.
+        if (semantics.kind == AccessKind.SUPER_METHOD) {
+          registry.registerStaticUse(semantics.element.declaration);
+        }
+        // TODO(johnniwinther): Remove this when all information goes through
+        // the [SendStructure].
+        registry.useElement(node, semantics.element);
+      }
+    } else {
+      visitExpression(expression);
+      semantics = new DynamicAccess.dynamicProperty(expression);
+      registry.registerDynamicInvocation(selector);
+    }
+    if (semantics != null) {
+      // TODO(johnniwinther): Support invalid super access as an
+      // [AccessSemantics].
+      registry.registerSendStructure(node,
+          new UnaryStructure(semantics, operator));
+    }
+    return null;
+  }
+
+  ResolutionResult handleNot(Send node, UnaryOperator operator) {
+    assert(invariant(node, operator.kind == UnaryOperatorKind.NOT));
+
+    Node expression = node.receiver;
+    visitExpression(expression);
+    registry.registerSendStructure(node,
+        new NotStructure(new DynamicAccess.dynamicProperty(expression)));
+    return null;
+  }
+
+  ResolutionResult handleLogicalAnd(Send node) {
+    Node left = node.receiver;
+    Node right = node.arguments.head;
+    doInPromotionScope(left, () => visitExpression(left));
+    doInPromotionScope(right, () => visitExpression(right));
+    registry.registerSendStructure(node, const LogicalAndStructure());
+    return null;
+  }
+
+  ResolutionResult handleLogicalOr(Send node) {
+    Node left = node.receiver;
+    Node right = node.arguments.head;
+    visitExpression(left);
+    visitExpression(right);
+    registry.registerSendStructure(node, const LogicalOrStructure());
+    return null;
+  }
+
+  ResolutionResult handleIfNull(Send node) {
+    Node left = node.receiver;
+    Node right = node.arguments.head;
+    visitExpression(left);
+    visitExpression(right);
+    registry.registerSendStructure(node, const IfNullStructure());
+    return null;
+  }
+
+  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 null;
+  }
+
+  ResolutionResult handleUserDefinableBinary(Send node,
+                                             BinaryOperator operator) {
+    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(johnniwinther): Remove this when all information goes through the
+    // [SendStructure].
+    registry.setSelector(node, selector);
+
+    if (node.isSuperCall) {
+      if (checkSuperAccess(node)) {
+        semantics = computeSuperSemantics(node, selector);
+        // TODO(johnniwinther): Add information to [AccessSemantics] about
+        // whether it is erroneous.
+        if (semantics.kind == AccessKind.SUPER_METHOD) {
+          registry.registerStaticUse(semantics.element.declaration);
+        }
+        // TODO(johnniwinther): Remove this when all information goes through
+        // the [SendStructure].
+        registry.useElement(node, semantics.element);
+
+      }
+    } else {
+      visitExpression(left);
+      registry.registerDynamicInvocation(selector);
+      semantics = new DynamicAccess.dynamicProperty(left);
+    }
+    visitExpression(right);
+
+    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:
+          internalError(node, "Unexpected binary operator '${operator}'.");
+          break;
+      }
+      registry.registerSendStructure(node, sendStructure);
+    }
+    return null;
+  }
+
   ResolutionResult visitSend(Send node) {
+    if (node.isOperator) {
+      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(invariant(node, operator.isUserDefinable,
+                  message: "Unexpected unary operator '${operator}'."));
+              return handleUserDefinableUnary(node, 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);
+          }
+        }
+      }
+    }
+
     bool oldSendIsMemberAccess = sendIsMemberAccess;
     sendIsMemberAccess = node.isPropertyAccess || node.isCall;
-    ResolutionResult result;
-    if (node.isLogicalAnd) {
-      result = doInPromotionScope(node.receiver, () => resolveSend(node));
-    } else {
-      result = resolveSend(node);
-    }
+
+    ResolutionResult result = resolveSend(node);
     sendIsMemberAccess = oldSendIsMemberAccess;
 
     Element target = result != null ? result.element : null;
@@ -2834,10 +1130,12 @@
       } else if (target.isAbstractField) {
         AbstractFieldElement field = target;
         target = field.getter;
-        if (target == null && !inInstanceContext) {
-          registry.registerThrowNoSuchMethod();
-          target = reportAndCreateErroneousElement(node.selector, field.name,
-              MessageKind.CANNOT_RESOLVE_GETTER, const {});
+        if (target == null) {
+          if (!inInstanceContext || field.isTopLevel || field.isStatic) {
+            registry.registerThrowNoSuchMethod();
+            target = reportAndCreateErroneousElement(node.selector, field.name,
+                MessageKind.CANNOT_RESOLVE_GETTER, const {});
+          }
         }
       } else if (target.isTypeVariable) {
         ClassElement cls = target.enclosingClass;
@@ -2849,39 +1147,9 @@
         }
         registry.registerClassUsingVariableExpression(cls);
         registry.registerTypeVariableExpression();
-        // Set the type of the node to [Type] to mark this send as a
-        // type variable expression.
-        registry.registerTypeLiteral(node, target.computeType(compiler));
+        registerTypeLiteralAccess(node, target);
       } else if (target.impliesType && (!sendIsMemberAccess || node.isCall)) {
-        // Set the type of the node to [Type] to mark this send as a
-        // type literal.
-        DartType type;
-
-        // TODO(johnniwinther): Remove this hack when we can pass more complex
-        // information between methods than resolved elements.
-        if (target == compiler.typeClass && node.receiver == null) {
-          // Potentially a 'dynamic' type literal.
-          type = registry.getType(node.selector);
-        }
-        if (type == null) {
-          type = target.computeType(compiler);
-        }
-        registry.registerTypeLiteral(node, type);
-
-        // Don't try to make constants of calls to type literals.
-        if (!node.isCall) {
-          analyzeConstantDeferred(node, enforceConst: false);
-        } else {
-          // The node itself is not a constant but we register the selector (the
-          // identifier that refers to the class/typedef) as a constant.
-          if (node.receiver != null) {
-            // This is a hack for the case of prefix.Type, we need to store
-            // the element on the selector, so [analyzeConstant] can build
-            // the type literal from the selector.
-            registry.useElement(node.selector, target);
-          }
-          analyzeConstantDeferred(node.selector, enforceConst: false);
-        }
+        registerTypeLiteralAccess(node, target);
       }
       if (isPotentiallyMutableTarget(target)) {
         if (enclosingElement != target.enclosingElement) {
@@ -2893,33 +1161,7 @@
     }
 
     bool resolvedArguments = false;
-    if (node.isOperator) {
-      String operatorString = node.selector.asOperator().source;
-      if (identical(operatorString, 'is')) {
-        // TODO(johnniwinther): Use seen type tests to avoid registration of
-        // mutation/access to unpromoted variables.
-        DartType type =
-            resolveTypeAnnotation(node.typeAnnotationFromIsCheckOrCast);
-        if (type != null) {
-          registry.registerIsCheck(type);
-        }
-        resolvedArguments = true;
-      } else if (identical(operatorString, 'as')) {
-        DartType type = resolveTypeAnnotation(node.arguments.head);
-        if (type != null) {
-          registry.registerAsCheck(type);
-        }
-        resolvedArguments = true;
-      } else if (identical(operatorString, '&&')) {
-        doInPromotionScope(node.arguments.head,
-            () => resolveArguments(node.argumentsNode));
-        resolvedArguments = true;
-      }
-    }
-
-    if (!resolvedArguments) {
-      resolveArguments(node.argumentsNode);
-    }
+    resolveArguments(node.argumentsNode);
 
     // If the selector is null, it means that we will not be generating
     // code for this as a send.
@@ -3012,10 +1254,12 @@
         AbstractFieldElement field = target;
         setter = field.setter;
         getter = field.getter;
-        if (setter == null && !inInstanceContext) {
-          setter = reportAndCreateErroneousElement(node.selector, field.name,
-              MessageKind.CANNOT_RESOLVE_SETTER, const {});
-          registry.registerThrowNoSuchMethod();
+        if (setter == null) {
+          if (!inInstanceContext || getter.isTopLevel || getter.isStatic) {
+            setter = reportAndCreateErroneousElement(node.selector, field.name,
+                MessageKind.CANNOT_RESOLVE_SETTER, const {});
+            registry.registerThrowNoSuchMethod();
+          }
         }
         if (isComplex && getter == null && !inInstanceContext) {
           getter = reportAndCreateErroneousElement(node.selector, field.name,
@@ -3023,9 +1267,17 @@
           registry.registerThrowNoSuchMethod();
         }
       } else if (target.impliesType) {
-        setter = reportAndCreateErroneousElement(node.selector, target.name,
-            MessageKind.ASSIGNING_TYPE, const {});
-        registry.registerThrowNoSuchMethod();
+        if (node.isIfNullAssignment) {
+          setter = reportAndCreateErroneousElement(node.selector, target.name,
+              MessageKind.IF_NULL_ASSIGNING_TYPE, const {});
+          // In this case, no assignment happens, the rest of the compiler can
+          // treat the expression `C ??= e` as if it's just reading `C`.
+        } else {
+          setter = reportAndCreateErroneousElement(node.selector, target.name,
+              MessageKind.ASSIGNING_TYPE, const {});
+          registry.registerThrowNoSuchMethod();
+        }
+        registerTypeLiteralAccess(node, target);
       } else if (target.isFinal || target.isConst) {
         if (Elements.isStaticOrTopLevelField(target) || target.isLocal) {
           setter = reportAndCreateErroneousElement(
@@ -3086,11 +1338,11 @@
       registerSend(getterSelector, getter);
       registry.setGetterSelectorInComplexSendSet(node, getterSelector);
       if (node.isSuperCall) {
-        getter = currentClass.lookupSuperSelector(getterSelector);
+        getter = currentClass.lookupSuperByName(getterSelector.memberName);
         if (getter == null) {
           target = reportAndCreateErroneousElement(
               node, selector.name, MessageKind.NO_SUCH_SUPER_MEMBER,
-              {'className': currentClass, 'memberName': selector.name});
+              {'className': currentClass.name, 'memberName': selector.name});
           registry.registerSuperNoSuchMethod();
         }
       }
@@ -3353,7 +1605,11 @@
   visitParenthesizedExpression(ParenthesizedExpression node) {
     bool oldSendIsMemberAccess = sendIsMemberAccess;
     sendIsMemberAccess = false;
+    var oldCategory = allowedCategory;
+    allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION
+        | ElementCategory.IMPLIES_TYPE;
     visit(node.expression);
+    allowedCategory = oldCategory;
     sendIsMemberAccess = oldSendIsMemberAccess;
   }
 
@@ -3774,7 +2030,6 @@
   }
 
   visitLiteralMap(LiteralMap node) {
-    bool oldSendIsMemberAccess = sendIsMemberAccess;
     sendIsMemberAccess = false;
 
     NodeList arguments = node.typeArguments;
@@ -3848,10 +2103,6 @@
   }
 
   void checkCaseExpressions(SwitchStatement node) {
-    JumpTarget breakElement = getOrDefineTarget(node);
-    Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{};
-
-    Link<Node> cases = node.cases.nodes;
     CaseMatch firstCase = null;
     DartType firstCaseType = null;
     bool hasReportedProblem = false;
@@ -4082,1087 +2333,8 @@
   }
 }
 
-class TypeDefinitionVisitor extends MappingVisitor<DartType> {
-  Scope scope;
-  final TypeDeclarationElement enclosingElement;
-  TypeDeclarationElement get element => enclosingElement;
-
-  TypeDefinitionVisitor(Compiler compiler,
-                        TypeDeclarationElement element,
-                        ResolutionRegistry registry)
-      : this.enclosingElement = element,
-        scope = Scope.buildEnclosingScope(element),
-        super(compiler, registry);
-
-  DartType get objectType => compiler.objectClass.rawType;
-
-  void resolveTypeVariableBounds(NodeList node) {
-    if (node == null) return;
-
-    Setlet<String> nameSet = new Setlet<String>();
-    // Resolve the bounds of type variables.
-    Iterator<DartType> types = element.typeVariables.iterator;
-    Link<Node> nodeLink = node.nodes;
-    while (!nodeLink.isEmpty) {
-      types.moveNext();
-      TypeVariableType typeVariable = types.current;
-      String typeName = typeVariable.name;
-      TypeVariable typeNode = nodeLink.head;
-      registry.useType(typeNode, typeVariable);
-      if (nameSet.contains(typeName)) {
-        error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
-              {'typeVariableName': typeName});
-      }
-      nameSet.add(typeName);
-
-      TypeVariableElementX variableElement = typeVariable.element;
-      if (typeNode.bound != null) {
-        DartType boundType = typeResolver.resolveTypeAnnotation(
-            this, typeNode.bound);
-        variableElement.boundCache = boundType;
-
-        void checkTypeVariableBound() {
-          Link<TypeVariableElement> seenTypeVariables =
-              const Link<TypeVariableElement>();
-          seenTypeVariables = seenTypeVariables.prepend(variableElement);
-          DartType 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.
-                warning(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());
-  }
-}
-
-class TypedefResolverVisitor extends TypeDefinitionVisitor {
-  TypedefElementX get element => enclosingElement;
-
-  TypedefResolverVisitor(Compiler compiler,
-                         TypedefElement typedefElement,
-                         ResolutionRegistry registry)
-      : super(compiler, typedefElement, registry);
-
-  visitTypedef(Typedef node) {
-    TypedefType type = element.computeType(compiler);
-    scope = new TypeDeclarationScope(scope, element);
-    resolveTypeVariableBounds(node.typeParameters);
-
-    FunctionSignature signature = SignatureResolver.analyze(
-        compiler, node.formals, node.returnType, element, registry,
-        defaultValuesError: MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT);
-    element.functionSignature = signature;
-
-    scope = new MethodScope(scope, element);
-    signature.forEachParameter(addToScope);
-
-    element.alias = signature.type;
-
-    void checkCyclicReference() {
-      element.checkCyclicReference(compiler);
-    }
-    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 BaseDartTypeVisitor {
-  final Compiler compiler;
-  final TypedefElementX element;
-  bool hasCyclicReference = false;
-
-  Link<TypedefElement> seenTypedefs = const Link<TypedefElement>();
-
-  int seenTypedefsCount = 0;
-
-  Link<TypeVariableElement> seenTypeVariables =
-      const Link<TypeVariableElement>();
-
-  TypedefCyclicVisitor(Compiler this.compiler, TypedefElement this.element);
-
-  visitType(DartType type, _) {
-    // Do nothing.
-  }
-
-  visitTypedefType(TypedefType 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.
-          compiler.reportError(element,
-              MessageKind.CYCLIC_TYPEDEF,
-              {'typedefName': element.name});
-        } else if (seenTypedefsCount == 2) {
-          // Cyclicity through one other typedef.
-          compiler.reportError(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)) {
-              compiler.reportError(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.alias =
-            new MalformedType(erroneousElement, typedefElement.alias);
-        element.hasBeenCheckedForCycles = true;
-      }
-    } else {
-      seenTypedefs = seenTypedefs.prepend(typedefElement);
-      seenTypedefsCount++;
-      type.visitChildren(this, null);
-      typedefElement.alias.accept(this, null);
-      seenTypedefs = seenTypedefs.tail;
-      seenTypedefsCount--;
-    }
-  }
-
-  visitFunctionType(FunctionType type, _) {
-    type.visitChildren(this, null);
-  }
-
-  visitInterfaceType(InterfaceType type, _) {
-    type.visitChildren(this, null);
-  }
-
-  visitTypeVariableType(TypeVariableType 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;
-  }
-}
-
-/**
- * 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(Compiler compiler,
-                       ClassElement classElement,
-                       ResolutionRegistry registry)
-    : super(compiler, classElement, registry);
-
-  DartType visitClassNode(ClassNode node) {
-    if (element == null) {
-      throw compiler.internalError(node, 'element is null');
-    }
-    if (element.resolutionState != STATE_STARTED) {
-      throw compiler.internalError(element,
-          'cyclic resolution of class $element');
-    }
-
-    InterfaceType type = element.computeType(compiler);
-    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) {
-        DartType supertype = resolveSupertype(element, superMixin.superclass);
-        Link<Node> link = superMixin.mixins.nodes;
-        while (!link.isEmpty) {
-          supertype = applyMixin(supertype,
-                                 checkMixinType(link.head), link.head);
-          link = link.tail;
-        }
-        element.supertype = supertype;
-      } 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) {
-          compiler.internalError(node,
-              "Cannot resolve default superclass for $element.");
-        } else {
-          superElement.ensureResolved(compiler);
-        }
-        element.supertype = superElement.computeType(compiler);
-      }
-    }
-
-    if (element.interfaces == null) {
-      element.interfaces = resolveInterfaces(node.interfaces, node.superclass);
-    } else {
-      assert(invariant(element, element.hasIncompleteHierarchy));
-    }
-    calculateAllSupertypes(element);
-
-    if (!element.hasConstructor) {
-      Element superMember = element.superclass.localLookup('');
-      if (superMember == null || !superMember.isGenerativeConstructor) {
-        MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR;
-        Map arguments = {'constructorName': ''};
-        // TODO(ahe): Why is this a compile-time error? Or if it is an error,
-        // why do we bother to registerThrowNoSuchMethod below?
-        compiler.reportError(node, kind, arguments);
-        superMember = new ErroneousElementX(
-            kind, arguments, '', element);
-        registry.registerThrowNoSuchMethod();
-      } else {
-        ConstructorElement superConstructor = superMember;
-        Selector callToMatch = new Selector.call("", element.library, 0);
-        superConstructor.computeSignature(compiler);
-        if (!callToMatch.applies(superConstructor, compiler.world)) {
-          MessageKind kind = MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT;
-          compiler.reportError(node, kind);
-          superMember = new ErroneousElementX(kind, {}, '', element);
-        }
-      }
-      FunctionElement constructor =
-          new SynthesizedConstructorElementX.forDefault(superMember, element);
-      if (superMember.isErroneous) {
-        compiler.elementsWithCompileTimeErrors.add(constructor);
-      }
-      element.setDefaultConstructor(constructor, compiler);
-    }
-    return element.computeType(compiler);
-  }
-
-  @override
-  DartType visitEnum(Enum node) {
-    if (element == null) {
-      throw compiler.internalError(node, 'element is null');
-    }
-    if (element.resolutionState != STATE_STARTED) {
-      throw compiler.internalError(element,
-          'cyclic resolution of class $element');
-    }
-
-    InterfaceType enumType = element.computeType(compiler);
-    element.supertype = compiler.objectClass.computeType(compiler);
-    element.interfaces = const Link<DartType>();
-    calculateAllSupertypes(element);
-
-    if (node.names.nodes.isEmpty) {
-      compiler.reportError(node,
-                           MessageKind.EMPTY_ENUM_DECLARATION,
-                           {'enumName': element.name});
-    }
-
-    EnumCreator creator = new EnumCreator(compiler, element);
-    creator.createMembers();
-    return enumType;
-  }
-
-  /// Resolves the mixed type for [mixinNode] and checks that the the mixin type
-  /// is a valid, non-blacklisted interface type. The mixin type is returned.
-  DartType checkMixinType(TypeAnnotation mixinNode) {
-    DartType mixinType = resolveType(mixinNode);
-    if (isBlackListed(mixinType)) {
-      compiler.reportError(mixinNode,
-          MessageKind.CANNOT_MIXIN, {'type': mixinType});
-    } else if (mixinType.isTypeVariable) {
-      compiler.reportError(mixinNode, MessageKind.CLASS_NAME_EXPECTED);
-    } else if (mixinType.isMalformed) {
-      compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED,
-          {'className': element.name, 'malformedType': mixinType});
-    } else if (mixinType.isEnumType) {
-      compiler.reportError(mixinNode, MessageKind.CANNOT_MIXIN_ENUM,
-          {'className': element.name, 'enumType': mixinType});
-    }
-    return mixinType;
-  }
-
-  DartType visitNamedMixinApplication(NamedMixinApplication node) {
-    if (element == null) {
-      throw compiler.internalError(node, 'element is null');
-    }
-    if (element.resolutionState != STATE_STARTED) {
-      throw compiler.internalError(element,
-          'cyclic resolution of class $element');
-    }
-
-    if (identical(node.classKeyword.stringValue, 'typedef')) {
-      // TODO(aprelev@gmail.com): Remove this deprecation diagnostic
-      // together with corresponding TODO in parser.dart.
-      compiler.reportWarning(node.classKeyword,
-          MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX);
-    }
-
-    InterfaceType type = element.computeType(compiler);
-    scope = new TypeDeclarationScope(scope, element);
-    resolveTypeVariableBounds(node.typeParameters);
-
-    // Generate anonymous mixin application elements for the
-    // intermediate mixin applications (excluding the last).
-    DartType supertype = resolveSupertype(element, node.superclass);
-    Link<Node> link = node.mixins.nodes;
-    while (!link.tail.isEmpty) {
-      supertype = applyMixin(supertype, checkMixinType(link.head), link.head);
-      link = link.tail;
-    }
-    doApplyMixinTo(element, supertype, checkMixinType(link.head));
-    return element.computeType(compiler);
-  }
-
-  DartType applyMixin(DartType supertype, DartType mixinType, Node node) {
-    String superName = supertype.name;
-    String mixinName = mixinType.name;
-    MixinApplicationElementX mixinApplication = new MixinApplicationElementX(
-        "${superName}+${mixinName}",
-        element.compilationUnit,
-        compiler.getNextFreeClassId(),
-        node,
-        new Modifiers.withFlags(new NodeList.empty(), Modifiers.FLAG_ABSTRACT));
-    // Create synthetic type variables for the mixin application.
-    List<DartType> typeVariables = <DartType>[];
-    element.typeVariables.forEach((TypeVariableType type) {
-      TypeVariableElementX typeVariableElement = new TypeVariableElementX(
-          type.name, mixinApplication, type.element.node);
-      TypeVariableType typeVariable = new TypeVariableType(typeVariableElement);
-      typeVariables.add(typeVariable);
-    });
-    // Setup bounds on the synthetic type variables.
-    List<DartType> link = typeVariables;
-    int index = 0;
-    element.typeVariables.forEach((TypeVariableType type) {
-      TypeVariableType typeVariable = typeVariables[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(compiler, 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).
-    InterfaceType mixinThisType = mixinApplication.computeType(compiler);
-    return mixinThisType.subst(element.typeVariables,
-                               mixinThisType.typeArguments);
-  }
-
-  bool isDefaultConstructor(FunctionElement constructor) {
-    return constructor.name == '' &&
-        constructor.computeSignature(compiler).parameterCount == 0;
-  }
-
-  FunctionElement createForwardingConstructor(ConstructorElement target,
-                                              ClassElement enclosing) {
-    return new SynthesizedConstructorElementX.notForDefault(
-        target.name, target, enclosing);
-  }
-
-  void doApplyMixinTo(MixinApplicationElementX mixinApplication,
-                      DartType supertype,
-                      DartType mixinType) {
-    Node node = mixinApplication.parseNode(compiler);
-
-    if (mixinApplication.supertype != null) {
-      // [supertype] is not null if there was a cycle.
-      assert(invariant(node, compiler.compilationFailed));
-      supertype = mixinApplication.supertype;
-      assert(invariant(node, supertype.element == compiler.objectClass));
-    } else {
-      mixinApplication.supertype = supertype;
-    }
-
-    // Named mixin application may have an 'implements' clause.
-    NamedMixinApplication namedMixinApplication =
-        node.asNamedMixinApplication();
-    Link<DartType> interfaces = (namedMixinApplication != null)
-        ? resolveInterfaces(namedMixinApplication.interfaces,
-                            namedMixinApplication.superclass)
-        : const Link<DartType>();
-
-    // 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(invariant(mixinApplication,
-          mixinApplication.hasIncompleteHierarchy));
-    }
-
-    ClassElement superclass = supertype.element;
-    if (mixinType.kind != TypeKind.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 (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);
-  }
-
-  InterfaceType resolveMixinFor(MixinApplicationElement mixinApplication,
-                                DartType mixinType) {
-    ClassElement mixin = mixinType.element;
-    mixin.ensureResolved(compiler);
-
-    // 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) {
-        compiler.reportError(
-            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;
-    }
-    registry.registerMixinUse(mixinApplication, mixin);
-    return mixinType;
-  }
-
-  DartType resolveType(TypeAnnotation node) {
-    return typeResolver.resolveTypeAnnotation(this, node);
-  }
-
-  DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) {
-    DartType supertype = resolveType(superclass);
-    if (supertype != null) {
-      if (supertype.isMalformed) {
-        compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_MALFORMED,
-            {'className': element.name, 'malformedType': supertype});
-        return objectType;
-      } else if (supertype.isEnumType) {
-        compiler.reportError(superclass, MessageKind.CANNOT_EXTEND_ENUM,
-            {'className': element.name, 'enumType': supertype});
-        return objectType;
-      } else if (!supertype.isInterfaceType) {
-        compiler.reportError(superclass.typeName,
-            MessageKind.CLASS_NAME_EXPECTED);
-        return objectType;
-      } else if (isBlackListed(supertype)) {
-        compiler.reportError(superclass, MessageKind.CANNOT_EXTEND,
-            {'type': supertype});
-        return objectType;
-      }
-    }
-    return supertype;
-  }
-
-  Link<DartType> resolveInterfaces(NodeList interfaces, Node superclass) {
-    Link<DartType> result = const Link<DartType>();
-    if (interfaces == null) return result;
-    for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) {
-      DartType interfaceType = resolveType(link.head);
-      if (interfaceType != null) {
-        if (interfaceType.isMalformed) {
-          compiler.reportError(superclass,
-              MessageKind.CANNOT_IMPLEMENT_MALFORMED,
-              {'className': element.name, 'malformedType': interfaceType});
-        } else if (interfaceType.isEnumType) {
-          compiler.reportError(superclass,
-              MessageKind.CANNOT_IMPLEMENT_ENUM,
-              {'className': element.name, 'enumType': interfaceType});
-        } else if (!interfaceType.isInterfaceType) {
-          // TODO(johnniwinther): Handle dynamic.
-          TypeAnnotation typeAnnotation = link.head;
-          error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED);
-        } else {
-          if (interfaceType == element.supertype) {
-            compiler.reportError(
-                superclass,
-                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
-                {'type': interfaceType});
-            compiler.reportError(
-                link.head,
-                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
-                {'type': interfaceType});
-          }
-          if (result.contains(interfaceType)) {
-            compiler.reportError(
-                link.head,
-                MessageKind.DUPLICATE_IMPLEMENTS,
-                {'type': interfaceType});
-          }
-          result = result.prepend(interfaceType);
-          if (isBlackListed(interfaceType)) {
-            error(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 DartType supertype = cls.supertype;
-    if (supertype != null) {
-      OrderedTypeSetBuilder allSupertypes = new OrderedTypeSetBuilder(cls);
-      // TODO(15296): Collapse these iterations to one when the order is not
-      // needed.
-      allSupertypes.add(compiler, supertype);
-      for (Link<DartType> interfaces = cls.interfaces;
-           !interfaces.isEmpty;
-           interfaces = interfaces.tail) {
-        allSupertypes.add(compiler, interfaces.head);
-      }
-
-      addAllSupertypes(allSupertypes, supertype);
-      for (Link<DartType> interfaces = cls.interfaces;
-           !interfaces.isEmpty;
-           interfaces = interfaces.tail) {
-        addAllSupertypes(allSupertypes, interfaces.head);
-      }
-      allSupertypes.add(compiler, cls.computeType(compiler));
-      cls.allSupertypesAndSelf = allSupertypes.toTypeSet();
-    } else {
-      assert(identical(cls, compiler.objectClass));
-      cls.allSupertypesAndSelf =
-          new OrderedTypeSet.singleton(cls.computeType(compiler));
-    }
-  }
-
-  /**
-   * Adds [type] and all supertypes of [type] to [allSupertypes] while
-   * substituting type variables.
-   */
-  void addAllSupertypes(OrderedTypeSetBuilder allSupertypes,
-                        InterfaceType type) {
-    ClassElement classElement = type.element;
-    Link<DartType> supertypes = classElement.allSupertypes;
-    assert(invariant(element, supertypes != null,
-        message: "Supertypes not computed on $classElement "
-                 "during resolution of $element"));
-    while (!supertypes.isEmpty) {
-      DartType supertype = supertypes.head;
-      allSupertypes.add(compiler, supertype.substByContext(type));
-      supertypes = supertypes.tail;
-    }
-  }
-
-  isBlackListed(DartType type) {
-    LibraryElement lib = element.library;
-    return
-      !identical(lib, compiler.coreLibrary) &&
-      !compiler.backend.isBackendLibrary(lib) &&
-      (type.isDynamic ||
-       identical(type.element, compiler.boolClass) ||
-       identical(type.element, compiler.numClass) ||
-       identical(type.element, compiler.intClass) ||
-       identical(type.element, compiler.doubleClass) ||
-       identical(type.element, compiler.stringClass) ||
-       identical(type.element, compiler.nullClass));
-  }
-}
-
-class ClassSupertypeResolver extends CommonResolverVisitor {
-  Scope context;
-  ClassElement classElement;
-
-  ClassSupertypeResolver(Compiler compiler, ClassElement cls)
-    : context = Scope.buildEnclosingScope(cls),
-      this.classElement = cls,
-      super(compiler);
-
-  void loadSupertype(ClassElement element, Node from) {
-    compiler.resolver.loadSupertypes(element, from);
-    element.ensureResolved(compiler);
-  }
-
-  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 (!identical(classElement, compiler.objectClass)) {
-        loadSupertype(compiler.objectClass, node);
-      }
-    } else {
-      node.superclass.accept(this);
-    }
-    visitNodeList(node.interfaces);
-  }
-
-  void visitEnum(Enum node) {
-    loadSupertype(compiler.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 visitTypeAnnotation(TypeAnnotation node) {
-    node.typeName.accept(this);
-  }
-
-  void visitIdentifier(Identifier node) {
-    Element element = lookupInScope(compiler, node, context, node.source);
-    if (element != null && element.isClass) {
-      loadSupertype(element, node);
-    }
-  }
-
-  void visitSend(Send node) {
-    Identifier prefix = node.receiver.asIdentifier();
-    if (prefix == null) {
-      error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
-      return;
-    }
-    Element element = lookupInScope(compiler, prefix, context, prefix.source);
-    if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
-      error(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) {
-      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE,
-            {'typeName': node.selector});
-      return;
-    }
-    loadSupertype(e, node);
-  }
-}
-
-class VariableDefinitionsVisitor extends CommonResolverVisitor<Identifier> {
-  VariableDefinitions definitions;
-  ResolverVisitor resolver;
-  VariableList variables;
-
-  VariableDefinitionsVisitor(Compiler compiler,
-                             this.definitions,
-                             this.resolver,
-                             this.variables)
-      : super(compiler) {
-  }
-
-  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) {
-      compiler.reportError(
-          identifier, MessageKind.REFERENCE_IN_INITIALIZATION,
-          {'variableName': name});
-    }
-    return identifier;
-  }
-
-  Identifier visitIdentifier(Identifier node) {
-    // The variable is initialized to null.
-    registry.registerInstantiatedClass(compiler.nullClass);
-    if (definitions.modifiers.isConst) {
-      compiler.reportError(node, MessageKind.CONST_WITHOUT_INITIALIZER);
-    }
-    if (definitions.modifiers.isFinal &&
-        !resolver.allowFinalWithoutInitializer) {
-      compiler.reportError(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) {
-        compiler.enqueuer.resolution.addDeferredAction(element, () {
-          element.constant =
-              compiler.resolver.constantCompiler.compileConstant(element);
-        });
-      }
-    }
-  }
-}
-
-class ConstructorResolver extends CommonResolverVisitor<Element> {
-  final ResolverVisitor resolver;
-  bool inConstContext;
-  DartType type;
-
-  ConstructorResolver(Compiler compiler, this.resolver,
-                      {bool this.inConstContext: false})
-      : super(compiler);
-
-  ResolutionRegistry get registry => resolver.registry;
-
-  visitNode(Node node) {
-    throw 'not supported';
-  }
-
-  ErroneousConstructorElementX failOrReturnErroneousConstructorElement(
-      Spannable diagnosticNode,
-      Element enclosing,
-      String name,
-      MessageKind kind,
-      Map arguments,
-      {bool isError: false,
-       bool missingConstructor: false}) {
-    if (missingConstructor) {
-      registry.registerThrowNoSuchMethod();
-    } else {
-      registry.registerThrowRuntimeError();
-    }
-    if (isError || inConstContext) {
-      compiler.reportError(diagnosticNode, kind, arguments);
-    } else {
-      compiler.reportWarning(diagnosticNode, kind, arguments);
-    }
-    return new ErroneousConstructorElementX(
-        kind, arguments, name, enclosing);
-  }
-
-  FunctionElement resolveConstructor(ClassElement cls,
-                                     Node diagnosticNode,
-                                     String constructorName) {
-    cls.ensureResolved(compiler);
-    Element result = cls.lookupConstructor(constructorName);
-    // TODO(johnniwinther): Use [Name] for lookup.
-    if (isPrivateName(constructorName) &&
-        resolver.enclosingElement.library != cls.library) {
-      result = null;
-    }
-    if (result == null) {
-      String fullConstructorName = Elements.constructorNameForDiagnostics(
-              cls.name,
-              constructorName);
-      return failOrReturnErroneousConstructorElement(
-          diagnosticNode,
-          cls, constructorName,
-          MessageKind.CANNOT_FIND_CONSTRUCTOR,
-          {'constructorName': fullConstructorName},
-          missingConstructor: true);
-    } else if (inConstContext && !result.isConst) {
-      error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
-    }
-    return result;
-  }
-
-  Element visitNewExpression(NewExpression node) {
-    inConstContext = node.isConst;
-    Node selector = node.send.selector;
-    Element element = visit(selector);
-    assert(invariant(selector, element != null,
-        message: 'No element return for $selector.'));
-    return finishConstructorReference(element, node.send.selector, node);
-  }
-
-  /// Finishes resolution of a constructor reference and records the
-  /// type of the constructed instance on [expression].
-  FunctionElement finishConstructorReference(Element element,
-                                             Node diagnosticNode,
-                                             Node expression) {
-    assert(invariant(diagnosticNode, element != null,
-        message: 'No element return for $diagnosticNode.'));
-    // Find the unnamed constructor if the reference resolved to a
-    // class.
-    if (!Elements.isUnresolved(element) && !element.isConstructor) {
-      if (element.isClass) {
-        ClassElement cls = element;
-        cls.ensureResolved(compiler);
-        // The unnamed constructor may not exist, so [e] may become unresolved.
-        element = resolveConstructor(cls, diagnosticNode, '');
-      } else {
-        element = failOrReturnErroneousConstructorElement(
-            diagnosticNode,
-            element, element.name,
-            MessageKind.NOT_A_TYPE, {'node': diagnosticNode});
-      }
-    } else if (element.isErroneous && element is! ErroneousElementX) {
-      // Parser error. The error has already been reported.
-      element = new ErroneousConstructorElementX(
-          MessageKind.NOT_A_TYPE, {'node': diagnosticNode},
-          element.name, element);
-      registry.registerThrowRuntimeError();
-    }
-
-    if (type == null) {
-      if (Elements.isUnresolved(element)) {
-        type = const DynamicType();
-      } else {
-        type = element.enclosingClass.rawType;
-      }
-    }
-    resolver.registry.setType(expression, type);
-    return element;
-  }
-
-  Element visitTypeAnnotation(TypeAnnotation node) {
-    assert(invariant(node, type == null));
-    // This is not really resolving a type-annotation, but the name of the
-    // constructor. Therefore we allow deferred types.
-    type = resolver.resolveTypeAnnotation(node,
-                                          malformedIsError: inConstContext,
-                                          deferredIsMalformed: false);
-    registry.registerRequiredType(type, resolver.enclosingElement);
-    return type.element;
-  }
-
-  Element visitSend(Send node) {
-    Element element = visit(node.receiver);
-    assert(invariant(node.receiver, element != null,
-        message: 'No element return for $node.receiver.'));
-    if (Elements.isUnresolved(element)) return element;
-    Identifier name = node.selector.asIdentifier();
-    if (name == null) internalError(node.selector, 'unexpected node');
-
-    if (element.isClass) {
-      ClassElement cls = element;
-      cls.ensureResolved(compiler);
-      return resolveConstructor(cls, name, name.source);
-    } else if (element.isPrefix) {
-      PrefixElement prefix = element;
-      element = prefix.lookupLocalMember(name.source);
-      element = Elements.unwrap(element, compiler, node);
-      if (element == null) {
-        return failOrReturnErroneousConstructorElement(
-            name,
-            resolver.enclosingElement, name.source,
-            MessageKind.CANNOT_RESOLVE, {'name': name});
-      } else if (!element.isClass) {
-        return failOrReturnErroneousConstructorElement(
-            name,
-            resolver.enclosingElement, name.source,
-            MessageKind.NOT_A_TYPE, {'node': name},
-            isError: true);
-      }
-    } else {
-      internalError(node.receiver, 'unexpected element $element');
-    }
-    return element;
-  }
-
-  Element visitIdentifier(Identifier node) {
-    String name = node.source;
-    Element element = resolver.reportLookupErrorIfAny(
-        lookupInScope(compiler, node, resolver.scope, name), node, name);
-    registry.useElement(node, element);
-    // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1.
-    if (element == null) {
-      return failOrReturnErroneousConstructorElement(
-          node,
-          resolver.enclosingElement, name,
-          MessageKind.CANNOT_RESOLVE,
-          {'name': name});
-    } else if (element.isErroneous) {
-      return element;
-    } else if (element.isTypedef) {
-      element = failOrReturnErroneousConstructorElement(
-          node,
-          resolver.enclosingElement, name,
-          MessageKind.CANNOT_INSTANTIATE_TYPEDEF, {'typedefName': name},
-          isError: true);
-    } else if (element.isTypeVariable) {
-      element = failOrReturnErroneousConstructorElement(
-          node,
-          resolver.enclosingElement, name,
-          MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
-          {'typeVariableName': name},
-          isError: true);
-    } else if (!element.isClass && !element.isPrefix) {
-      element = failOrReturnErroneousConstructorElement(
-          node,
-          resolver.enclosingElement, name,
-          MessageKind.NOT_A_TYPE, {'node': name},
-          isError: true);
-    }
-    return element;
-  }
-
-  /// Assumed to be called by [resolveRedirectingFactory].
-  Element visitRedirectingFactoryBody(RedirectingFactoryBody node) {
-    Node constructorReference = node.constructorReference;
-    return finishConstructorReference(visit(constructorReference),
-        constructorReference, node);
-  }
-}
-
 /// Looks up [name] in [scope] and unwraps the result.
 Element lookupInScope(Compiler compiler, Node node,
                       Scope scope, String name) {
   return Elements.unwrap(scope.lookup(name), compiler, node);
 }
-
-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(invariant(this, _treeElements !=null,
-        message: "TreeElements have not been computed for $this."));
-    return _treeElements;
-  }
-
-  void reuseElement() {
-    _treeElements = null;
-  }
-}
-
-/// The result of resolving a node.
-abstract class ResolutionResult {
-  Element get element;
-}
-
-/// The result for the resolution of a node that points to an [Element].
-class ElementResult implements ResolutionResult {
-  final Element element;
-
-  // TODO(johnniwinther): Remove this factory constructor when `null` is never
-  // passed as an element result.
-  factory ElementResult(Element element) {
-    return element != null ? new ElementResult.internal(element) : null;
-  }
-
-  ElementResult.internal(this.element);
-
-  String toString() => 'ElementResult($element)';
-}
-
-/// The result for the resolution of a node that points to an [DartType].
-class TypeResult implements ResolutionResult {
-  final DartType type;
-
-  TypeResult(this.type) {
-    assert(type != null);
-  }
-
-  Element get element => type.element;
-
-  String toString() => 'TypeResult($type)';
-}
-
-/// The result for the resolution of the `assert` method.
-class AssertResult implements ResolutionResult {
-  const AssertResult();
-
-  Element get element => null;
-
-  String toString() => 'AssertResult()';
-}
diff --git a/pkg/compiler/lib/src/resolution/operators.dart b/pkg/compiler/lib/src/resolution/operators.dart
index e862c30..594e0a0 100644
--- a/pkg/compiler/lib/src/resolution/operators.dart
+++ b/pkg/compiler/lib/src/resolution/operators.dart
@@ -5,6 +5,7 @@
 library dart2js.operators;
 
 import '../elements/elements.dart';
+import '../universe/universe.dart';
 
 enum UnaryOperatorKind {
   NOT,
@@ -21,6 +22,11 @@
 
   bool get isUserDefinable => selectorName != null;
 
+  Selector get selector => new Selector(
+      SelectorKind.OPERATOR,
+      new PublicName(selectorName),
+      CallStructure.NO_ARGS);
+
   String toString() => name;
 
   /// The unary ! operator.
@@ -66,6 +72,7 @@
   XOR,
   LOGICAL_AND,
   LOGICAL_OR,
+  IF_NULL,
 }
 
 class BinaryOperator {
@@ -161,6 +168,10 @@
   static const BinaryOperator LOGICAL_OR =
       const _LogicalOperator(BinaryOperatorKind.LOGICAL_OR, '||');
 
+  /// The if-null ?? operator.
+  static const BinaryOperator IF_NULL =
+      const _LogicalOperator(BinaryOperatorKind.IF_NULL, '??');
+
   static BinaryOperator parse(String value) {
     switch (value) {
       case '==': return EQ;
@@ -183,6 +194,7 @@
       case '|': return OR;
       case '&&': return LOGICAL_AND;
       case '||': return LOGICAL_OR;
+      case '??': return IF_NULL;
       default: return null;
     }
   }
@@ -211,6 +223,7 @@
 
 enum AssignmentOperatorKind {
   ASSIGN,
+  IF_NULL,
   ADD,
   SUB,
   MUL,
@@ -244,6 +257,12 @@
       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, '+=',
@@ -302,6 +321,7 @@
   static AssignmentOperator parse(String value) {
     switch (value) {
       case '=': return ASSIGN;
+      case '??=': return IF_NULL;
       case '*=': return MUL;
       case '/=': return DIV;
       case '%=': return MOD;
@@ -349,4 +369,4 @@
       default: return null;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index 00ee9a5..70209b2 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -379,6 +379,10 @@
     return mapping.isAssert(node);
   }
 
+  void registerSendStructure(Send node, SendStructure sendStructure) {
+    mapping.setSendStructure(node, sendStructure);
+  }
+
   void registerAsyncMarker(FunctionElement element) {
     backend.registerAsyncMarker(element, world, this);
   }
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 7b8bf65..2073cac 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -11,7 +11,7 @@
 import '../constants/values.dart';
 import '../dart_backend/dart_backend.dart' show DartBackend;
 import '../dart_types.dart';
-import '../dart2jslib.dart';
+import '../dart2jslib.dart' hide DynamicAccess;
 import '../tree/tree.dart';
 import '../scanner/scannerlib.dart';
 import '../elements/elements.dart';
@@ -49,11 +49,23 @@
 import '../util/util.dart';
 import '../universe/universe.dart' show CallStructure;
 
+import 'access_semantics.dart';
 import 'class_members.dart' show MembersCreator;
 import 'enum_creator.dart';
+import 'operators.dart';
 import 'secret_tree_element.dart' show getTreeElement, setTreeElement;
+import 'send_structure.dart';
 
+part 'class_hierarchy.dart';
+part 'constructors.dart';
+part 'label_scope.dart';
 part 'members.dart';
 part 'registry.dart';
+part 'resolution_common.dart';
+part 'resolution_result.dart';
 part 'scope.dart';
 part 'signatures.dart';
+part 'tree_elements.dart';
+part 'typedefs.dart';
+part 'type_resolver.dart';
+part 'variables.dart';
diff --git a/pkg/compiler/lib/src/resolution/resolution_common.dart b/pkg/compiler/lib/src/resolution/resolution_common.dart
new file mode 100644
index 0000000..6f257f4
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/resolution_common.dart
@@ -0,0 +1,1049 @@
+// 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 resolution;
+
+class ResolverTask extends CompilerTask {
+  final ConstantCompiler constantCompiler;
+
+  ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler);
+
+  String get name => 'Resolver';
+
+  TreeElements resolve(Element element) {
+    return measure(() {
+      if (Elements.isErroneous(element)) return null;
+
+      processMetadata([result]) {
+        for (MetadataAnnotation metadata in element.metadata) {
+          metadata.ensureResolved(compiler);
+        }
+        return result;
+      }
+
+      ElementKind kind = element.kind;
+      if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) ||
+          identical(kind, ElementKind.FUNCTION) ||
+          identical(kind, ElementKind.GETTER) ||
+          identical(kind, ElementKind.SETTER)) {
+        return processMetadata(resolveMethodElement(element));
+      }
+
+      if (identical(kind, ElementKind.FIELD)) {
+        return processMetadata(resolveField(element));
+      }
+      if (element.isClass) {
+        ClassElement cls = element;
+        cls.ensureResolved(compiler);
+        return processMetadata();
+      } else if (element.isTypedef) {
+        TypedefElement typdef = element;
+        return processMetadata(resolveTypedef(typdef));
+      }
+
+      compiler.unimplemented(element, "resolve($element)");
+    });
+  }
+
+  void resolveRedirectingConstructor(InitializerResolver resolver,
+                                     Node node,
+                                     FunctionElement constructor,
+                                     FunctionElement redirection) {
+    assert(invariant(node, constructor.isImplementation,
+        message: '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 (seen.contains(redirection)) {
+        resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
+        return;
+      }
+      seen.add(redirection);
+      redirection = resolver.visitor.resolveConstructorRedirection(redirection);
+    }
+  }
+
+  static void processAsyncMarker(Compiler compiler,
+                                 BaseFunctionElementX element,
+                                 Registry registry) {
+    FunctionExpression functionExpression = element.node;
+    AsyncModifier asyncModifier = functionExpression.asyncModifier;
+    if (asyncModifier != null) {
+
+      if (asyncModifier.isAsynchronous) {
+        element.asyncMarker = asyncModifier.isYielding
+            ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC;
+      } else {
+        element.asyncMarker = AsyncMarker.SYNC_STAR;
+      }
+      if (element.isAbstract) {
+        compiler.reportError(asyncModifier,
+            MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
+            {'modifier': element.asyncMarker});
+      } else if (element.isConstructor) {
+        compiler.reportError(asyncModifier,
+            MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
+            {'modifier': element.asyncMarker});
+      } else {
+        if (element.isSetter) {
+          compiler.reportError(asyncModifier,
+              MessageKind.ASYNC_MODIFIER_ON_SETTER,
+              {'modifier': element.asyncMarker});
+
+        }
+        if (functionExpression.body.asReturn() != null &&
+            element.asyncMarker.isYielding) {
+          compiler.reportError(asyncModifier,
+              MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
+              {'modifier': element.asyncMarker});
+        }
+      }
+      registry.registerAsyncMarker(element);
+      switch (element.asyncMarker) {
+      case AsyncMarker.ASYNC:
+        compiler.futureClass.ensureResolved(compiler);
+        break;
+      case AsyncMarker.ASYNC_STAR:
+        compiler.streamClass.ensureResolved(compiler);
+        break;
+      case AsyncMarker.SYNC_STAR:
+        compiler.iterableClass.ensureResolved(compiler);
+        break;
+      }
+    }
+  }
+
+  bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) {
+    assert(classElement != null);
+    while (classElement != null) {
+      if (classElement.isNative) return true;
+      classElement = classElement.superclass;
+    }
+    return false;
+  }
+
+  TreeElements resolveMethodElementImplementation(
+      FunctionElement element, FunctionExpression tree) {
+    return compiler.withCurrentElement(element, () {
+      if (element.isExternal && tree.hasBody()) {
+        error(element,
+            MessageKind.EXTERNAL_WITH_BODY,
+            {'functionName': element.name});
+      }
+      if (element.isConstructor) {
+        if (tree.returnType != null) {
+          error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
+        }
+        if (element.isConst &&
+            tree.hasBody() &&
+            !tree.isRedirectingFactory) {
+          error(tree, MessageKind.CONST_CONSTRUCTOR_HAS_BODY);
+        }
+      }
+
+      ResolverVisitor visitor = visitorFor(element);
+      ResolutionRegistry registry = visitor.registry;
+      registry.defineFunction(tree, element);
+      visitor.setupFunction(tree, element);
+      processAsyncMarker(compiler, 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);
+        FunctionElement redirection =
+            resolver.resolveInitializers(element, tree);
+        if (redirection != null) {
+          resolveRedirectingConstructor(resolver, tree, element, redirection);
+        }
+      } else if (tree.initializers != null) {
+        error(tree, MessageKind.FUNCTION_WITH_INITIALIZER);
+      }
+
+      if (!compiler.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.
+        Iterable<MixinApplicationElement> mixinUses =
+            compiler.world.allMixinUsesOf(enclosingClass);
+        ClassElement mixin = enclosingClass;
+        for (MixinApplicationElement mixinApplication in mixinUses) {
+          checkMixinSuperUses(resolutionTree, mixinApplication, mixin);
+        }
+      }
+
+      // TODO(9631): support noSuchMethod on native classes.
+      if (Elements.isInstanceMethod(element) &&
+          element.name == Compiler.NO_SUCH_METHOD &&
+          _isNativeClassOrExtendsNativeClass(enclosingClass)) {
+        error(tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE);
+      }
+
+      return resolutionTree;
+    });
+
+  }
+
+  TreeElements resolveMethodElement(FunctionElementX element) {
+    assert(invariant(element, element.isDeclaration));
+    return compiler.withCurrentElement(element, () {
+      if (compiler.enqueuer.resolution.hasBeenResolved(element)) {
+        // TODO(karlklose): Remove the check for [isConstructor]. [elememts]
+        // should never be non-null, not even for constructors.
+        assert(invariant(element, element.isConstructor,
+            message: 'Non-constructor element $element '
+                     'has already been analyzed.'));
+        return element.resolvedAst.elements;
+      }
+      if (element.isSynthesized) {
+        if (element.isGenerativeConstructor) {
+          ResolutionRegistry registry =
+              new ResolutionRegistry(compiler, 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.
+          element.computeSignature(compiler);
+          if (!target.isErroneous) {
+            registry.registerStaticUse(target);
+            registry.registerImplicitSuperCall(target);
+          }
+          return registry.mapping;
+        } else {
+          assert(element.isDeferredLoaderGetter || element.isErroneous);
+          return _ensureTreeElements(element);
+        }
+      } else {
+        element.parseNode(compiler);
+        element.computeType(compiler);
+        FunctionElementX implementation = element;
+        if (element.isExternal) {
+          implementation = compiler.backend.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(compiler, element,
+        new ResolutionRegistry(compiler, element),
+        useEnclosingScope: useEnclosingScope);
+  }
+
+  TreeElements resolveField(FieldElementX element) {
+    VariableDefinitions tree = element.parseNode(compiler);
+    if(element.modifiers.isStatic && element.isTopLevel) {
+      error(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(tree.definitions.nodes.head, element);
+    // TODO(johnniwinther): Share the resolved type between all variables
+    // declared in the same declaration.
+    if (tree.type != null) {
+      element.variables.type = visitor.resolveTypeAnnotation(tree.type);
+    } else {
+      element.variables.type = const DynamicType();
+    }
+
+    Expression initializer = element.initializer;
+    Modifiers modifiers = element.modifiers;
+    if (initializer != null) {
+      // TODO(johnniwinther): Avoid analyzing initializers if
+      // [Compiler.analyzeSignaturesOnly] is set.
+      visitor.visit(initializer);
+    } else if (modifiers.isConst) {
+      compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER);
+    } else if (modifiers.isFinal && !element.isInstanceMember) {
+      compiler.reportError(element, MessageKind.FINAL_WITHOUT_INITIALIZER);
+    } else {
+      registry.registerInstantiatedClass(compiler.nullClass);
+    }
+
+    if (Elements.isStaticOrTopLevelField(element)) {
+      visitor.addDeferredAction(element, () {
+        if (element.modifiers.isConst) {
+          element.constant = constantCompiler.compileConstant(element);
+        } else {
+          constantCompiler.compileVariable(element);
+        }
+      });
+      if (initializer != null) {
+        if (!element.modifiers.isConst) {
+          // TODO(johnniwinther): Determine the const-ness eagerly to avoid
+          // unnecessary registrations.
+          registry.registerLazyField();
+        }
+      }
+    }
+
+    // Perform various checks as side effect of "computing" the type.
+    element.computeType(compiler);
+
+    return registry.mapping;
+  }
+
+  DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) {
+    DartType type = resolveReturnType(element, annotation);
+    if (type.isVoid) {
+      error(annotation, MessageKind.VOID_NOT_ALLOWED);
+    }
+    return type;
+  }
+
+  DartType resolveReturnType(Element element, TypeAnnotation annotation) {
+    if (annotation == null) return const DynamicType();
+    DartType result = visitorFor(element).resolveTypeAnnotation(annotation);
+    if (result == null) {
+      // TODO(karklose): warning.
+      return const DynamicType();
+    }
+    return result;
+  }
+
+  void resolveRedirectionChain(ConstructorElementX constructor,
+                               Spannable node) {
+    ConstructorElementX target = constructor;
+    InterfaceType targetType;
+    List<Element> seen = new List<Element>();
+    // Follow the chain of redirections and check for cycles.
+    while (target.isRedirectingFactory) {
+      if (target.internalEffectiveTarget != null) {
+        // We found a constructor that already has been processed.
+        targetType = target.effectiveTargetType;
+        assert(invariant(target, targetType != null,
+            message: 'Redirection target type has not been computed for '
+                     '$target'));
+        target = target.internalEffectiveTarget;
+        break;
+      }
+
+      Element nextTarget = target.immediateRedirectionTarget;
+      if (seen.contains(nextTarget)) {
+        error(node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
+        targetType = target.enclosingClass.thisType;
+        break;
+      }
+      seen.add(target);
+      target = nextTarget;
+    }
+
+    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();
+
+      // [factory] must already be analyzed but the [TreeElements] might not
+      // have been stored in the enqueuer cache yet.
+      // TODO(johnniwinther): Store [TreeElements] in the cache before
+      // resolution of the element.
+      TreeElements treeElements = factory.treeElements;
+      assert(invariant(node, treeElements != null,
+          message: 'No TreeElements cached for $factory.'));
+      FunctionExpression functionNode = factory.parseNode(compiler);
+      RedirectingFactoryBody redirectionNode = functionNode.body;
+      DartType factoryType = treeElements.getType(redirectionNode);
+      if (!factoryType.isDynamic) {
+        targetType = targetType.substByContext(factoryType);
+      }
+      factory.effectiveTarget = target;
+      factory.effectiveTargetType = targetType;
+    }
+  }
+
+  /**
+   * 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) {
+    compiler.withCurrentElement(cls, () => measure(() {
+      if (cls.supertypeLoadState == STATE_DONE) return;
+      if (cls.supertypeLoadState == STATE_STARTED) {
+        compiler.reportError(from, MessageKind.CYCLIC_CLASS_HIERARCHY,
+                                 {'className': cls.name});
+        cls.supertypeLoadState = STATE_DONE;
+        cls.hasIncompleteHierarchy = true;
+        cls.allSupertypesAndSelf =
+            compiler.objectClass.allSupertypesAndSelf.extendClass(
+                cls.computeType(compiler));
+        cls.supertype = cls.allSupertypes.head;
+        assert(invariant(from, cls.supertype != null,
+            message: 'Missing supertype on cyclic class $cls.'));
+        cls.interfaces = const Link<DartType>();
+        return;
+      }
+      cls.supertypeLoadState = STATE_STARTED;
+      compiler.withCurrentElement(cls, () {
+        // TODO(ahe): Cache the node in cls.
+        cls.parseNode(compiler).accept(
+            new ClassSupertypeResolver(compiler, 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.
+  TypeDeclarationElement currentlyResolvedTypeDeclaration;
+  Queue<ClassElement> pendingClassesToBeResolved = new Queue<ClassElement>();
+  Queue<ClassElement> pendingClassesToBePostProcessed =
+      new Queue<ClassElement>();
+
+  /// Resolve [element] using [resolveTypeDeclaration].
+  ///
+  /// This methods ensure 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 compiler.withCurrentElement(element, () {
+      return measure(() {
+        TypeDeclarationElement previousResolvedTypeDeclaration =
+            currentlyResolvedTypeDeclaration;
+        currentlyResolvedTypeDeclaration = element;
+        var result = resolveTypeDeclaration();
+        if (previousResolvedTypeDeclaration == null) {
+          do {
+            while (!pendingClassesToBeResolved.isEmpty) {
+              pendingClassesToBeResolved.removeFirst().ensureResolved(compiler);
+            }
+            while (!pendingClassesToBePostProcessed.isEmpty) {
+              _postProcessClassElement(
+                  pendingClassesToBePostProcessed.removeFirst());
+            }
+          } while (!pendingClassesToBeResolved.isEmpty);
+          assert(pendingClassesToBeResolved.isEmpty);
+          assert(pendingClassesToBePostProcessed.isEmpty);
+        }
+        currentlyResolvedTypeDeclaration = previousResolvedTypeDeclaration;
+        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(compiler):].
+   */
+  TreeElements resolveClass(BaseClassElementX element) {
+    return _resolveTypeDeclaration(element, () {
+      // TODO(johnniwinther): Store the mapping in the resolution enqueuer.
+      ResolutionRegistry registry = new ResolutionRegistry(compiler, element);
+      resolveClassInternal(element, registry);
+      return element.treeElements;
+    });
+  }
+
+  void _ensureClassWillBeResolved(ClassElement element) {
+    if (currentlyResolvedTypeDeclaration == null) {
+      element.ensureResolved(compiler);
+    } else {
+      pendingClassesToBeResolved.add(element);
+    }
+  }
+
+  void resolveClassInternal(BaseClassElementX element,
+                            ResolutionRegistry registry) {
+    if (!element.isPatch) {
+      compiler.withCurrentElement(element, () => measure(() {
+        assert(element.resolutionState == STATE_NOT_STARTED);
+        element.resolutionState = STATE_STARTED;
+        Node tree = element.parseNode(compiler);
+        loadSupertypes(element, tree);
+
+        ClassResolverVisitor visitor =
+            new ClassResolverVisitor(compiler, element, registry);
+        visitor.visit(tree);
+        element.resolutionState = STATE_DONE;
+        compiler.onClassResolved(element);
+        pendingClassesToBePostProcessed.add(element);
+      }));
+      if (element.isPatched) {
+        // Ensure handling patch after origin.
+        element.patch.ensureResolved(compiler);
+      }
+    } else { // Handle patch classes:
+      element.resolutionState = STATE_STARTED;
+      // Ensure handling origin before patch.
+      element.origin.ensureResolved(compiler);
+      // Ensure that the type is computed.
+      element.computeType(compiler);
+      // 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.metadata) {
+      metadata.ensureResolved(compiler);
+      if (!element.isProxy &&
+          metadata.constant.value == compiler.proxyConstant) {
+        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) {
+        compiler.withCurrentElement(member, () {
+          for (MetadataAnnotation metadata in member.metadata) {
+            metadata.ensureResolved(compiler);
+          }
+        });
+      }
+    });
+
+    computeClassMember(element, Compiler.CALL_OPERATOR_NAME);
+  }
+
+  void computeClassMembers(ClassElement element) {
+    MembersCreator.computeAllClassMembers(compiler, element);
+  }
+
+  void computeClassMember(ClassElement element, String name) {
+    MembersCreator.computeClassMembersByName(compiler, 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);
+      compiler.reportError(
+          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) {
+      compiler.reportError(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) {
+      compiler.reportError(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((AstElement member) {
+      if (member.isGenerativeConstructor && !member.isSynthesized) {
+        compiler.reportError(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 (compiler.enqueuer.resolution.hasBeenResolved(member)) {
+          checkMixinSuperUses(
+              member.resolvedAst.elements,
+              mixinApplication,
+              mixin);
+        }
+      }
+    });
+  }
+
+  void checkMixinSuperUses(TreeElements resolutionTree,
+                           MixinApplicationElement mixinApplication,
+                           ClassElement mixin) {
+    // TODO(johnniwinther): Avoid the use of [TreeElements] here.
+    if (resolutionTree == null) return;
+    Iterable<Node> superUses = resolutionTree.superUses;
+    if (superUses.isEmpty) return;
+    compiler.reportError(mixinApplication,
+                         MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
+                         {'className': mixin.name});
+    // Show the user the problematic uses of 'super' in the mixin.
+    for (Node use in superUses) {
+      compiler.reportInfo(
+          use,
+          MessageKind.ILLEGAL_MIXIN_SUPER_USE);
+    }
+  }
+
+  void checkClassMembers(ClassElement cls) {
+    assert(invariant(cls, cls.isDeclaration));
+    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, member) {
+      compiler.withCurrentElement(member, () {
+        // Perform various checks as side effect of "computing" the type.
+        member.computeType(compiler);
+
+        // Check modifiers.
+        if (member.isFunction && member.modifiers.isFinal) {
+          compiler.reportError(
+              member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
+        }
+        if (member.isConstructor) {
+          final mismatchedFlagsBits =
+              member.modifiers.flags &
+              (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT);
+          if (mismatchedFlagsBits != 0) {
+            final mismatchedFlags =
+                new Modifiers.withFlags(null, mismatchedFlagsBits);
+            compiler.reportError(
+                member,
+                MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
+                {'modifiers': mismatchedFlags});
+          }
+          if (member.modifiers.isConst) {
+            constConstructors.add(member);
+          }
+        }
+        if (member.isField) {
+          if (member.modifiers.isConst && !member.modifiers.isStatic) {
+            compiler.reportError(
+                member, MessageKind.ILLEGAL_CONST_FIELD_MODIFIER);
+          }
+          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];
+      compiler.reportError(span,
+          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
+          {'className': cls.name});
+      if (constConstructors.length > 1) {
+        for (Element constructor in constConstructors) {
+          compiler.reportInfo(constructor,
+              MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR);
+        }
+      }
+      for (Element field in nonFinalInstanceFields) {
+        compiler.reportInfo(field,
+            MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD);
+      }
+    }
+  }
+
+  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) {
+      compiler.internalError(member,
+          "No abstract field for accessor");
+    } else if (!identical(lookupElement.kind, ElementKind.ABSTRACT_FIELD)) {
+      if (lookupElement.isErroneous || lookupElement.isAmbiguous) return;
+      compiler.internalError(member,
+          "Inaccessible abstract field for accessor");
+    }
+    AbstractFieldElement field = lookupElement;
+
+    MethodElementX getter = field.getter;
+    if (getter == null) return;
+    MethodElementX setter = field.setter;
+    if (setter == null) return;
+    int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
+    int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
+    if (!identical(getterFlags, setterFlags)) {
+      final mismatchedFlags =
+        new Modifiers.withFlags(null, getterFlags ^ setterFlags);
+      compiler.reportError(
+          field.getter,
+          MessageKind.GETTER_MISMATCH,
+          {'modifiers': mismatchedFlags});
+      compiler.reportError(
+          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 {
+      compiler.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;
+    compiler.reportHint(
+        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;
+        }
+      }
+      compiler.reportError(
+          errorNode, messageKind, {'operatorName': function.name});
+    }
+    if (signature.optionalParameterCount != 0) {
+      Node errorNode =
+          node.parameters.nodes.skip(signature.requiredParameterCount).head;
+      if (signature.optionalParametersAreNamed) {
+        compiler.reportError(
+            errorNode,
+            MessageKind.OPERATOR_NAMED_PARAMETERS,
+            {'operatorName': function.name});
+      } else {
+        compiler.reportError(
+            errorNode,
+            MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
+            {'operatorName': function.name});
+      }
+    }
+  }
+
+  reportErrorWithContext(Element errorneousElement,
+                         MessageKind errorMessage,
+                         Element contextElement,
+                         MessageKind contextMessage) {
+    compiler.reportError(
+        errorneousElement,
+        errorMessage,
+        {'memberName': contextElement.name,
+         'className': contextElement.enclosingClass.name});
+    compiler.reportInfo(contextElement, contextMessage);
+  }
+
+
+  FunctionSignature resolveSignature(FunctionElementX element) {
+    MessageKind defaultValuesError = null;
+    if (element.isFactoryConstructor) {
+      FunctionExpression body = element.parseNode(compiler);
+      if (body.isRedirectingFactory) {
+        defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT;
+      }
+    }
+    return compiler.withCurrentElement(element, () {
+      FunctionExpression node =
+          compiler.parser.measure(() => element.parseNode(compiler));
+      return measure(() => SignatureResolver.analyze(
+          compiler, node.parameters, node.returnType, element,
+          new ResolutionRegistry(compiler, element),
+          defaultValuesError: defaultValuesError,
+          createRealParameters: true));
+    });
+  }
+
+  TreeElements resolveTypedef(TypedefElementX element) {
+    if (element.isResolved) return element.treeElements;
+    compiler.world.allTypedefs.add(element);
+    return _resolveTypeDeclaration(element, () {
+      ResolutionRegistry registry = new ResolutionRegistry(compiler, element);
+      return compiler.withCurrentElement(element, () {
+        return measure(() {
+          assert(element.resolutionState == STATE_NOT_STARTED);
+          element.resolutionState = STATE_STARTED;
+          Typedef node =
+            compiler.parser.measure(() => element.parseNode(compiler));
+          TypedefResolverVisitor visitor =
+            new TypedefResolverVisitor(compiler, element, registry);
+          visitor.visit(node);
+          element.resolutionState = STATE_DONE;
+          return registry.mapping;
+        });
+      });
+    });
+  }
+
+  void resolveMetadataAnnotation(MetadataAnnotationX annotation) {
+    compiler.withCurrentElement(annotation.annotatedElement, () => measure(() {
+      assert(annotation.resolutionState == STATE_NOT_STARTED);
+      annotation.resolutionState = STATE_STARTED;
+
+      Node node = annotation.parseNode(compiler);
+      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(compiler);
+      }
+      assert(invariant(node, context != null,
+          message: "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].
+      annotation.constant =
+          constantCompiler.compileMetadata(annotation, node, registry.mapping);
+      // 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).
+      registry.registerMetadataConstant(annotation, annotatedElement);
+      annotation.resolutionState = STATE_DONE;
+    }));
+  }
+
+  error(Spannable node, MessageKind kind, [arguments = const {}]) {
+    compiler.reportError(node, kind, arguments);
+  }
+
+  Link<MetadataAnnotation> resolveMetadata(Element element,
+                                           VariableDefinitions node) {
+    LinkBuilder<MetadataAnnotation> metadata =
+        new LinkBuilder<MetadataAnnotation>();
+    for (Metadata annotation in node.metadata.nodes) {
+      ParameterMetadataAnnotation metadataAnnotation =
+          new ParameterMetadataAnnotation(annotation);
+      metadataAnnotation.annotatedElement = element;
+      metadata.addLast(metadataAnnotation.ensureResolved(compiler));
+    }
+    return metadata.toLink();
+  }
+}
+
+class CommonResolverVisitor<R> extends Visitor<R> {
+  final Compiler compiler;
+
+  CommonResolverVisitor(Compiler this.compiler);
+
+  R visitNode(Node node) {
+    internalError(node,
+        'internal error: Unhandled node: ${node.getObjectDescription()}');
+    return null;
+  }
+
+  R visitEmptyStatement(Node node) => null;
+
+  /** Convenience method for visiting nodes that may be null. */
+  R visit(Node node) => (node == null) ? null : node.accept(this);
+
+  void error(Spannable node, MessageKind kind, [Map arguments = const {}]) {
+    compiler.reportError(node, kind, arguments);
+  }
+
+  void warning(Spannable node, MessageKind kind, [Map arguments = const {}]) {
+    compiler.reportWarning(node, kind, arguments);
+  }
+
+  void internalError(Spannable node, message) {
+    compiler.internalError(node, message);
+  }
+
+  void addDeferredAction(Element element, DeferredAction action) {
+    compiler.enqueuer.resolution.addDeferredAction(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(Compiler compiler, ResolutionRegistry this.registry)
+      : typeResolver = new TypeResolver(compiler),
+        super(compiler);
+
+  AsyncMarker get currentAsyncMarker => AsyncMarker.SYNC;
+
+  /// Add [element] to the current scope and check for duplicate definitions.
+  void addToScope(Element element) {
+    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') {
+        compiler.reportError(
+            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 compiler.internalError(node, 'element is null');
+    }
+    checkLocalDefinitionName(node, element);
+    registry.defineElement(node, element);
+  }
+
+  void reportDuplicateDefinition(String name,
+                                 Spannable definition,
+                                 Spannable existing) {
+    compiler.reportError(definition,
+        MessageKind.DUPLICATE_DEFINITION, {'name': name});
+    compiler.reportInfo(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
new file mode 100644
index 0000000..fd2344e
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/resolution_result.dart
@@ -0,0 +1,47 @@
+// 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 resolution;
+
+/// The result of resolving a node.
+abstract class ResolutionResult {
+  Element get element;
+}
+
+/// The result for the resolution of a node that points to an [Element].
+class ElementResult implements ResolutionResult {
+  final Element element;
+
+  // TODO(johnniwinther): Remove this factory constructor when `null` is never
+  // passed as an element result.
+  factory ElementResult(Element element) {
+    return element != null ? new ElementResult.internal(element) : null;
+  }
+
+  ElementResult.internal(this.element);
+
+  String toString() => 'ElementResult($element)';
+}
+
+/// The result for the resolution of a node that points to an [DartType].
+class TypeResult implements ResolutionResult {
+  final DartType type;
+
+  TypeResult(this.type) {
+    assert(type != null);
+  }
+
+  Element get element => type.element;
+
+  String toString() => 'TypeResult($type)';
+}
+
+/// The result for the resolution of the `assert` method.
+class AssertResult implements ResolutionResult {
+  const AssertResult();
+
+  Element get element => null;
+
+  String toString() => 'AssertResult()';
+}
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor.dart b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
index b1c1f31..f90db1c 100644
--- a/pkg/compiler/lib/src/resolution/semantic_visitor.dart
+++ b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
@@ -96,9 +96,9 @@
       for (Node node in initializers) {
         InitializerStructure structure = computeInitializerStructure(node);
         if (structure == null) {
-          return internalError(node, 'No structure for $node');
+          internalError(node, 'No structure for $node');
         } else {
-          return structure.dispatch(declVisitor, node, arg);
+          structure.dispatch(declVisitor, node, arg);
         }
       }
     }
@@ -175,7 +175,7 @@
   ///       parameter = rhs;
   ///     }
   ///
-  R errorFinalParameterSet(
+  R visitFinalParameterSet(
       SendSet node,
       ParameterElement parameter,
       Node rhs,
@@ -230,7 +230,7 @@
   ///       variable = rhs;
   ///     }
   ///
-  R errorFinalLocalVariableSet(
+  R visitFinalLocalVariableSet(
       SendSet node,
       LocalVariableElement variable,
       Node rhs,
@@ -272,7 +272,7 @@
   ///       o = rhs;
   ///     }
   ///
-  R errorLocalFunctionSet(
+  R visitLocalFunctionSet(
       SendSet node,
       LocalFunctionElement function,
       Node rhs,
@@ -304,6 +304,18 @@
       Selector selector,
       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,
+      Selector selector,
+      A arg);
+
   /// Setter call on [receiver] with argument [rhs] of the property defined by
   /// [selector].
   ///
@@ -319,6 +331,21 @@
       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,
+      Selector selector,
+      Node rhs,
+      A arg);
+
   /// Invocation of the property defined by [selector] on [receiver] with
   /// [arguments].
   ///
@@ -334,6 +361,21 @@
       Selector selector,
       A arg);
 
+  /// Conditinal 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
@@ -457,7 +499,7 @@
   ///        m() { super.foo = rhs; }
   ///     }
   ///
-  R errorFinalSuperFieldSet(
+  R visitFinalSuperFieldSet(
       SendSet node,
       FieldElement field,
       Node rhs,
@@ -539,7 +581,7 @@
   ///        m() { super.foo = rhs; }
   ///     }
   ///
-  R errorSuperMethodSet(
+  R visitSuperMethodSet(
       Send node,
       MethodElement method,
       Node rhs,
@@ -570,7 +612,7 @@
   ///        m() => super.foo;
   ///     }
   ///
-  R errorSuperSetterGet(
+  R visitSuperSetterGet(
       Send node,
       FunctionElement setter,
       A arg);
@@ -601,7 +643,7 @@
   ///        m() { super.foo = rhs; }
   ///     }
   ///
-  R errorSuperGetterSet(
+  R visitSuperGetterSet(
       SendSet node,
       FunctionElement getter,
       Node rhs,
@@ -634,7 +676,7 @@
   ///        m() { super.foo(null, 42; }
   ///     }
   ///
-  R errorSuperSetterInvoke(
+  R visitSuperSetterInvoke(
       Send node,
       FunctionElement setter,
       NodeList arguments,
@@ -688,7 +730,7 @@
   ///     }
   ///     m() { C.foo = rhs; }
   ///
-  R errorFinalStaticFieldSet(
+  R visitFinalStaticFieldSet(
       SendSet node,
       FieldElement field,
       Node rhs,
@@ -760,7 +802,7 @@
   ///     }
   ///     m() { C.foo = rhs; }
   ///
-  R errorStaticFunctionSet(
+  R visitStaticFunctionSet(
       Send node,
       MethodElement function,
       Node rhs,
@@ -787,7 +829,7 @@
   ///     }
   ///     m() => C.foo;
   ///
-  R errorStaticSetterGet(
+  R visitStaticSetterGet(
       Send node,
       FunctionElement setter,
       A arg);
@@ -814,7 +856,7 @@
   ///     }
   ///     m() { C.foo = rhs; }
   ///
-  R errorStaticGetterSet(
+  R visitStaticGetterSet(
       SendSet node,
       FunctionElement getter,
       Node rhs,
@@ -843,7 +885,7 @@
   ///     }
   ///     m() { C.foo(null, 42; }
   ///
-  R errorStaticSetterInvoke(
+  R visitStaticSetterInvoke(
       Send node,
       FunctionElement setter,
       NodeList arguments,
@@ -879,7 +921,7 @@
   ///     final foo = null;
   ///     m() { foo = rhs; }
   ///
-  R errorFinalTopLevelFieldSet(
+  R visitFinalTopLevelFieldSet(
       SendSet node,
       FieldElement field,
       Node rhs,
@@ -943,7 +985,7 @@
   ///     foo(a, b) {};
   ///     m() { foo = rhs; }
   ///
-  R errorTopLevelFunctionSet(
+  R visitTopLevelFunctionSet(
       Send node,
       MethodElement function,
       Node rhs,
@@ -966,7 +1008,7 @@
   ///     set foo(_) {}
   ///     m() => foo;
   ///
-  R errorTopLevelSetterGet(
+  R visitTopLevelSetterGet(
       Send node,
       FunctionElement setter,
       A arg);
@@ -989,7 +1031,7 @@
   ///     get foo => null;
   ///     m() { foo = rhs; }
   ///
-  R errorTopLevelGetterSet(
+  R visitTopLevelGetterSet(
       SendSet node,
       FunctionElement getter,
       Node rhs,
@@ -1014,7 +1056,7 @@
   ///     set foo(_) {};
   ///     m() { foo(null, 42); }
   ///
-  R errorTopLevelSetterInvoke(
+  R visitTopLevelSetterInvoke(
       Send node,
       FunctionElement setter,
       NodeList arguments,
@@ -1051,7 +1093,7 @@
   ///     class C {}
   ///     m() { C = rhs; }
   ///
-  R errorClassTypeLiteralSet(
+  R visitClassTypeLiteralSet(
       SendSet node,
       ConstantExpression constant,
       Node rhs,
@@ -1087,7 +1129,7 @@
   ///     typedef F();
   ///     m() { F = rhs; }
   ///
-  R errorTypedefTypeLiteralSet(
+  R visitTypedefTypeLiteralSet(
       SendSet node,
       ConstantExpression constant,
       Node rhs,
@@ -1127,7 +1169,7 @@
   ///       m() { T = rhs; }
   ///     }
   ///
-  R errorTypeVariableTypeLiteralSet(
+  R visitTypeVariableTypeLiteralSet(
       SendSet node,
       TypeVariableElement element,
       Node rhs,
@@ -1160,7 +1202,7 @@
   /// For instance
   ///     m() { dynamic = rhs; }
   ///
-  R errorDynamicTypeLiteralSet(
+  R visitDynamicTypeLiteralSet(
       SendSet node,
       ConstantExpression constant,
       Node rhs,
@@ -1352,11 +1394,13 @@
       A arg);
 
   /// Prefix operation on an index expression `operator super[index]` where
-  /// 'operator []' and maybe also 'operator []=' is unresolved and the
-  /// operation is defined by [operator].
+  /// 'operator []' is unresolved, 'operator []=' is defined by [setter], and
+  /// the operation is defined by [operator].
   ///
   /// For instance:
-  ///     class B {}
+  ///     class B {
+  ///       operator []=(a, b) {}
+  ///     }
   ///     class C extends B {
   ///       m(a) => --super[a];
   ///     }
@@ -1364,16 +1408,19 @@
   R visitUnresolvedSuperGetterIndexPrefix(
       Send node,
       Element element,
+      MethodElement setter,
       Node index,
       IncDecOperator operator,
       A arg);
 
   /// Postfix operation on an index expression `super[index] operator` where
-  /// 'operator []' and maybe also 'operator []=' is unresolved and the
-  /// operation is defined by [operator].
+  /// 'operator []' is unresolved, 'operator []=' is defined by [setter], and
+  /// the operation is defined by [operator].
   ///
   /// For instance:
-  ///     class B {}
+  ///     class B {
+  ///       operator []=(a, b) {}
+  ///     }
   ///     class C extends B {
   ///       m(a) => super[a]++;
   ///     }
@@ -1381,6 +1428,7 @@
   R visitUnresolvedSuperGetterIndexPostfix(
       Send node,
       Element element,
+      MethodElement setter,
       Node index,
       IncDecOperator operator,
       A arg);
@@ -1390,7 +1438,9 @@
   /// 'operator []=' is unresolved and the operation is defined by [operator].
   ///
   /// For instance:
-  ///     class B {}
+  ///     class B {
+  ///       operator [](_) => 42;
+  ///     }
   ///     class C extends B {
   ///       m(a) => --super[a];
   ///     }
@@ -1408,7 +1458,9 @@
   /// 'operator []=' is unresolved and the operation is defined by [operator].
   ///
   /// For instance:
-  ///     class B {}
+  ///     class B {
+  ///       operator [](_) => 42;
+  ///     }
   ///     class C extends B {
   ///       m(a) => super[a]++;
   ///     }
@@ -1421,6 +1473,44 @@
       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:
@@ -1579,6 +1669,17 @@
       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
@@ -1654,6 +1755,22 @@
       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,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      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.
   ///
@@ -1692,7 +1809,7 @@
   /// For instance:
   ///     m(final parameter, rhs) => parameter += rhs;
   ///
-  R errorFinalParameterCompound(
+  R visitFinalParameterCompound(
       Send node,
       ParameterElement parameter,
       AssignmentOperator operator,
@@ -1724,7 +1841,7 @@
   ///       variable += rhs;
   ///     }
   ///
-  R errorFinalLocalVariableCompound(
+  R visitFinalLocalVariableCompound(
       Send node,
       LocalVariableElement variable,
       AssignmentOperator operator,
@@ -1740,7 +1857,7 @@
   ///       function += rhs;
   ///     }
   ///
-  R errorLocalFunctionCompound(
+  R visitLocalFunctionCompound(
       Send node,
       LocalFunctionElement function,
       AssignmentOperator operator,
@@ -1772,7 +1889,7 @@
   ///       m(rhs) => field += rhs;
   ///     }
   ///
-  R errorFinalStaticFieldCompound(
+  R visitFinalStaticFieldCompound(
       Send node,
       FieldElement field,
       AssignmentOperator operator,
@@ -1810,8 +1927,8 @@
   ///
   R visitStaticMethodSetterCompound(
       Send node,
-      FunctionElement method,
-      FunctionElement setter,
+      MethodElement method,
+      MethodElement setter,
       AssignmentOperator operator,
       Node rhs,
       A arg);
@@ -1837,7 +1954,7 @@
   ///     final field = 0;
   ///     m(rhs) => field += rhs;
   ///
-  R errorFinalTopLevelFieldCompound(
+  R visitFinalTopLevelFieldCompound(
       Send node,
       FieldElement field,
       AssignmentOperator operator,
@@ -1877,6 +1994,21 @@
       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,
+      FunctionElement method,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
   /// Compound assignment expression of [rhs] with [operator] on a super
   /// [field].
   ///
@@ -1900,19 +2032,121 @@
   ///
   /// For instance:
   ///     class B {
-  ///       final field = 0;
+  ///       final field = 42;
   ///     }
   ///     class C extends B {
   ///       m(rhs) => super.field += rhs;
   ///     }
   ///
-  R errorFinalSuperFieldCompound(
+  R visitFinalSuperFieldCompound(
       Send node,
       FieldElement field,
       AssignmentOperator operator,
       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(
+      Send 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(
+      Send 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].
   ///
@@ -1954,6 +2188,62 @@
       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,
+      FunctionElement 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(
+      Send node,
+      Element element,
+      MethodElement 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,
+      MethodElement 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].
   ///
@@ -2005,7 +2295,7 @@
   ///     class C {}
   ///     m(rhs) => C += rhs;
   ///
-  R errorClassTypeLiteralCompound(
+  R visitClassTypeLiteralCompound(
       Send node,
       ConstantExpression constant,
       AssignmentOperator operator,
@@ -2019,7 +2309,7 @@
   ///     typedef F();
   ///     m(rhs) => F += rhs;
   ///
-  R errorTypedefTypeLiteralCompound(
+  R visitTypedefTypeLiteralCompound(
       Send node,
       ConstantExpression constant,
       AssignmentOperator operator,
@@ -2034,7 +2324,7 @@
   ///       m(rhs) => T += rhs;
   ///     }
   ///
-  R errorTypeVariableTypeLiteralCompound(
+  R visitTypeVariableTypeLiteralCompound(
       Send node,
       TypeVariableElement element,
       AssignmentOperator operator,
@@ -2047,7 +2337,7 @@
   /// For instance:
   ///     m(rhs) => dynamic += rhs;
   ///
-  R errorDynamicTypeLiteralCompound(
+  R visitDynamicTypeLiteralCompound(
       Send node,
       ConstantExpression constant,
       AssignmentOperator operator,
@@ -2091,8 +2381,8 @@
       A arg);
 
   /// Compound index assignment of [rhs] with [operator] to [index] on a super
-  /// super class where the index getter is undefined. The index setter might
-  /// also be undefined.
+  /// super class where the index getter is undefined and the index setter is
+  /// defined by [setter].
   ///
   /// For instance
   ///     class B {
@@ -2104,6 +2394,7 @@
   R visitUnresolvedSuperGetterCompoundIndexSet(
       Send node,
       Element element,
+      MethodElement setter,
       Node index,
       AssignmentOperator operator,
       Node rhs,
@@ -2130,6 +2421,24 @@
       Node rhs,
       A arg);
 
+  /// Compound index assignment of [rhs] with [operator] to [index] on a super
+  /// super class where the index getter and setter are undefined.
+  ///
+  /// For instance
+  ///     class B {
+  ///     }
+  ///     class C extends B {
+  ///       m() => super[1] += 42;
+  ///     }
+  ///
+  R visitUnresolvedSuperCompoundIndexSet(
+      Send node,
+      Element element,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
   /// Prefix expression with [operator] of the property on [receiver] whose
   /// getter and setter are defined by [getterSelector] and [setterSelector],
   /// respectively.
@@ -2145,6 +2454,21 @@
       Selector setterSelector,
       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,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg);
+
   /// Prefix expression with [operator] on a [parameter].
   ///
   /// For instance:
@@ -2156,6 +2480,17 @@
       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:
@@ -2170,6 +2505,20 @@
       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:
@@ -2178,7 +2527,7 @@
   ///      ++function;
   ///     }
   ///
-  R errorLocalFunctionPrefix(
+  R visitLocalFunctionPrefix(
       Send node,
       LocalFunctionElement function,
       IncDecOperator operator,
@@ -2219,6 +2568,20 @@
       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].
   ///
@@ -2266,6 +2629,18 @@
       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].
   ///
@@ -2414,13 +2789,69 @@
       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,
+      FunctionElement 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(
+      Send node,
+      Element element,
+      MethodElement 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(
+      Send node,
+      MethodElement 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 errorClassTypeLiteralPrefix(
+  R visitClassTypeLiteralPrefix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -2433,7 +2864,7 @@
   ///     typedef F();
   ///     m() => ++F;
   ///
-  R errorTypedefTypeLiteralPrefix(
+  R visitTypedefTypeLiteralPrefix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -2447,7 +2878,7 @@
   ///       m() => ++T;
   ///     }
   ///
-  R errorTypeVariableTypeLiteralPrefix(
+  R visitTypeVariableTypeLiteralPrefix(
       Send node,
       TypeVariableElement element,
       IncDecOperator operator,
@@ -2458,7 +2889,7 @@
   /// For instance:
   ///     m() => ++dynamic;
   ///
-  R errorDynamicTypeLiteralPrefix(
+  R visitDynamicTypeLiteralPrefix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -2479,6 +2910,21 @@
       Selector setterSelector,
       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,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg);
+
   /// Postfix expression with [operator] on a [parameter].
   ///
   /// For instance:
@@ -2490,12 +2936,23 @@
       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++;
+  ///       var variable;
+  ///       variable++;
   ///     }
   ///
   R visitLocalVariablePostfix(
@@ -2504,6 +2961,20 @@
       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:
@@ -2512,7 +2983,7 @@
   ///      function++;
   ///     }
   ///
-  R errorLocalFunctionPostfix(
+  R visitLocalFunctionPostfix(
       Send node,
       LocalFunctionElement function,
       IncDecOperator operator,
@@ -2553,6 +3024,20 @@
       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].
   ///
@@ -2600,6 +3085,18 @@
       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].
   ///
@@ -2748,6 +3245,62 @@
       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,
+      FunctionElement 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(
+      Send node,
+      Element element,
+      MethodElement 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(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg);
+
   /// Postfix expression with [operator] on a type literal for a class
   /// [element].
   ///
@@ -2755,7 +3308,7 @@
   ///     class C {}
   ///     m() => C++;
   ///
-  R errorClassTypeLiteralPostfix(
+  R visitClassTypeLiteralPostfix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -2768,7 +3321,7 @@
   ///     typedef F();
   ///     m() => F++;
   ///
-  R errorTypedefTypeLiteralPostfix(
+  R visitTypedefTypeLiteralPostfix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -2782,7 +3335,7 @@
   ///       m() => T++;
   ///     }
   ///
-  R errorTypeVariableTypeLiteralPostfix(
+  R visitTypeVariableTypeLiteralPostfix(
       Send node,
       TypeVariableElement element,
       IncDecOperator operator,
@@ -2793,7 +3346,7 @@
   /// For instance:
   ///     m() => dynamic++;
   ///
-  R errorDynamicTypeLiteralPostfix(
+  R visitDynamicTypeLiteralPostfix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -2834,6 +3387,10 @@
   ///     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(
@@ -2865,9 +3422,13 @@
   ///     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 errorUnresolvedSet(
+  R visitUnresolvedSet(
       Send node,
       Element element,
       Node rhs,
@@ -2884,6 +3445,10 @@
   ///     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(
@@ -2908,7 +3473,87 @@
       Selector selector,
       A arg);
 
-  /// Compound assignment of [rhs] on the unresolved [element].
+  /// 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,
+      MethodElement 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,
+      MethodElement 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,
+      MethodElement 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,
+      MethodElement 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 {}
@@ -2919,16 +3564,110 @@
   ///     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 errorUnresolvedCompound(
+  R visitUnresolvedCompound(
       Send node,
       Element element,
       AssignmentOperator operator,
       Node rhs,
       A arg);
 
-  /// Prefix operation on the unresolved [element].
+  /// 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,
+      MethodElement 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,
+      MethodElement 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,
+      MethodElement 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,
+      MethodElement 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 {}
@@ -2939,15 +3678,109 @@
   ///     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 errorUnresolvedPrefix(
+  R visitUnresolvedPrefix(
       Send node,
       Element element,
       IncDecOperator operator,
       A arg);
 
-  /// Postfix operation on the unresolved [element].
+  /// 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,
+      MethodElement 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,
+      MethodElement 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,
+      MethodElement 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,
+      MethodElement 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 {}
@@ -2958,9 +3791,13 @@
   ///     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 errorUnresolvedPostfix(
+  R visitUnresolvedPostfix(
       Send node,
       Element element,
       IncDecOperator operator,
@@ -3125,7 +3962,7 @@
   R errorNonConstantConstructorInvoke(
       NewExpression node,
       Element element,
-      InterfaceType type,
+      DartType type,
       NodeList arguments,
       CallStructure callStructure,
       A arg);
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart b/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
index 7f5b884..69665d7 100644
--- a/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
+++ b/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
@@ -33,217 +33,10 @@
   }
 
   @override
-  R errorClassTypeLiteralCompound(
-      Send node,
-      ConstantExpression constant,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorClassTypeLiteralPostfix(
-      Send node,
-      ConstantExpression constant,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorClassTypeLiteralPrefix(
-      Send node,
-      ConstantExpression constant,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorClassTypeLiteralSet(
-      SendSet node,
-      ConstantExpression constant,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorDynamicTypeLiteralCompound(
-      Send node,
-      ConstantExpression constant,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorDynamicTypeLiteralPostfix(
-      Send node,
-      ConstantExpression constant,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorDynamicTypeLiteralPrefix(
-      Send node,
-      ConstantExpression constant,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorDynamicTypeLiteralSet(
-      SendSet node,
-      ConstantExpression constant,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorFinalLocalVariableCompound(
-      Send node,
-      LocalVariableElement
-      variable,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorFinalLocalVariableSet(
-      SendSet node,
-      LocalVariableElement variable,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorFinalParameterCompound(
-      Send node,
-      ParameterElement parameter,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorFinalParameterSet(
-      SendSet node,
-      ParameterElement parameter,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorFinalStaticFieldCompound(
-      Send node,
-      FieldElement field,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorFinalStaticFieldSet(
-      SendSet node,
-      FieldElement field,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorFinalSuperFieldCompound(
-      Send node,
-      FieldElement field,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorFinalSuperFieldSet(
-      SendSet node,
-      FieldElement field,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorFinalTopLevelFieldCompound(
-      Send node,
-      FieldElement field,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorFinalTopLevelFieldSet(
-      SendSet node,
-      FieldElement field,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorLocalFunctionCompound(
-      Send node,
-      LocalFunctionElement function,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorLocalFunctionPostfix(
-      Send node,
-      LocalFunctionElement function,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorLocalFunctionPrefix(
-      Send node,
-      LocalFunctionElement function,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorLocalFunctionSet(
-      SendSet node,
-      LocalFunctionElement function,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
   R errorNonConstantConstructorInvoke(
       NewExpression node,
       Element element,
-      InterfaceType type,
+      DartType type,
       NodeList arguments,
       CallStructure callStructure,
       A arg) {
@@ -251,225 +44,6 @@
   }
 
   @override
-  R errorStaticFunctionSet(
-      Send node,
-      MethodElement function,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorStaticGetterSet(
-      SendSet node,
-      FunctionElement getter,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorStaticSetterGet(
-      Send node,
-      FunctionElement setter,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorStaticSetterInvoke(
-      Send node,
-      FunctionElement setter,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorSuperGetterSet(
-      SendSet node,
-      FunctionElement getter,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorSuperMethodSet(
-      Send node,
-      MethodElement method,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorSuperSetterGet(
-      Send node,
-      FunctionElement setter,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorSuperSetterInvoke(
-      Send node,
-      FunctionElement setter,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTopLevelFunctionSet(
-      Send node,
-      MethodElement function,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTopLevelGetterSet(
-      SendSet node,
-      FunctionElement getter,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTopLevelSetterGet(
-      Send node,
-      FunctionElement setter,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTopLevelSetterInvoke(
-      Send node,
-      FunctionElement setter,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTypeVariableTypeLiteralCompound(
-      Send node,
-      TypeVariableElement element,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTypeVariableTypeLiteralPostfix(
-      Send node,
-      TypeVariableElement element,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTypeVariableTypeLiteralPrefix(
-      Send node,
-      TypeVariableElement element,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTypeVariableTypeLiteralSet(
-      SendSet node,
-      TypeVariableElement element,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTypedefTypeLiteralCompound(
-      Send node,
-      ConstantExpression constant,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTypedefTypeLiteralPostfix(
-      Send node,
-      ConstantExpression constant,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTypedefTypeLiteralPrefix(
-      Send node,
-      ConstantExpression constant,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorTypedefTypeLiteralSet(
-      SendSet node,
-      ConstantExpression constant,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorUnresolvedCompound(
-      Send node,
-      Element element,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorUnresolvedPostfix(
-      Send node,
-      Element element,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorUnresolvedPrefix(
-      Send node,
-      Element element,
-      IncDecOperator operator,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
-  R errorUnresolvedSet(
-      Send node,
-      Element element,
-      Node rhs,
-      A arg) {
-    return bulkHandleError(node, arg);
-  }
-
-  @override
   R errorUndefinedUnaryExpression(
       Send node,
       Operator operator,
@@ -512,6 +86,16 @@
     return bulkHandlePrefix(node, arg);
   }
 
+  R visitIfNotNullDynamicPropertyPrefix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return bulkHandlePrefix(node, arg);
+  }
+
   @override
   R visitIndexPrefix(
       Send node,
@@ -633,6 +217,7 @@
   R visitUnresolvedSuperGetterIndexPrefix(
       Send node,
       Element element,
+      MethodElement setter,
       Node index,
       IncDecOperator operator,
       A arg) {
@@ -651,6 +236,16 @@
   }
 
   @override
+  R visitUnresolvedSuperIndexPrefix(
+      Send node,
+      Element element,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node, arg);
+  }
+
+  @override
   R visitSuperMethodSetterPrefix(
       Send node,
       FunctionElement method,
@@ -698,6 +293,201 @@
       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,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node, arg);
+  }
+
+  @override
+  R visitUnresolvedTopLevelSetterPrefix(
+      Send node,
+      MethodElement 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,
+      Element 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,
+      FunctionElement 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(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node, arg);
+  }
+
+  @override
+  R visitUnresolvedSuperGetterPrefix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node, arg);
+  }
+
+  @override
+  R visitUnresolvedSuperSetterPrefix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node, arg);
+  }
 }
 
 /// Mixin that implements all `visitXPostfix` methods of [SemanticSendVisitor]
@@ -724,6 +514,16 @@
   }
 
   @override
+  R visitIfNotNullDynamicPropertyPostfix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return bulkHandlePostfix(node, arg);
+  }
+
   R visitIndexPostfix(
       Send node,
       Node receiver,
@@ -844,6 +644,7 @@
   R visitUnresolvedSuperGetterIndexPostfix(
       Send node,
       Element element,
+      MethodElement setter,
       Node index,
       IncDecOperator operator,
       A arg) {
@@ -862,6 +663,16 @@
   }
 
   @override
+  R visitUnresolvedSuperIndexPostfix(
+      Send node,
+      Element element,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node, arg);
+  }
+
+  @override
   R visitSuperMethodSetterPostfix(
       Send node,
       FunctionElement method,
@@ -909,6 +720,209 @@
       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,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node, arg);
+  }
+
+  @override
+  R visitUnresolvedTopLevelSetterPostfix(
+      Send node,
+      MethodElement 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,
+      Element 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,
+      FunctionElement 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(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node, arg);
+  }
+
+  @override
+  R visitUnresolvedSuperGetterPostfix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node, arg);
+  }
+
+  @override
+  R visitUnresolvedSuperSetterPostfix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node, arg);
+  }
 }
 
 /// Mixin that implements all `visitXCompound` methods of [SemanticSendVisitor]
@@ -936,6 +950,18 @@
   }
 
   @override
+  R visitIfNotNullDynamicPropertyCompound(
+      Send node,
+      Node receiver,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return bulkHandleCompound(node, arg);
+  }
+
+  @override
   R visitLocalVariableCompound(
       Send node,
       LocalVariableElement variable,
@@ -1083,6 +1109,231 @@
       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,
+      MethodElement getter,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node, arg);
+  }
+
+  @override
+  R visitUnresolvedTopLevelSetterCompound(
+      Send node,
+      MethodElement 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,
+      Element 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,
+      FunctionElement 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(
+      Send node, Element element,
+      MethodElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node, arg);
+  }
+
+  @override
+  R visitUnresolvedSuperSetterCompound(
+      Send node, MethodElement getter,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node, arg);
+  }
 }
 
 /// Mixin that implements all `visitXInvoke` methods of [SemanticSendVisitor] by
@@ -1118,6 +1369,16 @@
   }
 
   @override
+  R visitIfNotNullDynamicPropertyInvoke(
+      Send node,
+      Node receiver,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node, arg);
+  }
+
+  @override
   R visitDynamicTypeLiteralInvoke(
       Send node,
       ConstantExpression constant,
@@ -1354,6 +1615,36 @@
       A arg) {
     return bulkHandleInvoke(node, arg);
   }
+
+  @override
+  R visitStaticSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      CallStructure callStructure,
+      A arg) {
+    return bulkHandleInvoke(node, arg);
+  }
+
+  @override
+  R visitSuperSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      CallStructure callStructure,
+      A arg) {
+    return bulkHandleInvoke(node, arg);
+  }
+
+  @override
+  R visitTopLevelSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      CallStructure callStructure,
+      A arg) {
+    return bulkHandleInvoke(node, arg);
+  }
 }
 
 /// Mixin that implements all `visitXGet` methods of [SemanticSendVisitor] by
@@ -1386,6 +1677,15 @@
   }
 
   @override
+  R visitIfNotNullDynamicPropertyGet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      A arg) {
+    return bulkHandleGet(node, arg);
+  }
+
+  @override
   R visitDynamicTypeLiteralGet(
       Send node,
       ConstantExpression constant,
@@ -1541,6 +1841,30 @@
       A arg) {
     return bulkHandleGet(node, arg);
   }
+
+  @override
+  R visitStaticSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg) {
+    return bulkHandleGet(node, arg);
+  }
+
+  @override
+  R visitSuperSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg) {
+    return bulkHandleGet(node, arg);
+  }
+
+  @override
+  R visitTopLevelSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg) {
+    return bulkHandleGet(node, arg);
+  }
 }
 
 /// Mixin that implements all `visitXSet` methods of [SemanticSendVisitor] by
@@ -1566,6 +1890,16 @@
   }
 
   @override
+  R visitIfNotNullDynamicPropertySet(
+      SendSet node,
+      Node receiver,
+      Selector selector,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node, arg);
+  }
+
+  @override
   R visitLocalVariableSet(
       SendSet node,
       LocalVariableElement variable,
@@ -1645,6 +1979,159 @@
       A arg) {
     return bulkHandleSet(node, arg);
   }
+
+  @override
+  R visitClassTypeLiteralSet(
+      SendSet node,
+      ConstantExpression constant,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node, arg);
+  }
+
+  @override
+  R visitDynamicTypeLiteralSet(
+      SendSet node,
+      ConstantExpression 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(
+      Send node,
+      MethodElement function,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node, arg);
+  }
+
+  @override
+  R visitStaticGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node, arg);
+  }
+
+  @override
+  R visitSuperGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node, arg);
+  }
+
+  @override
+  R visitSuperMethodSet(
+      Send node,
+      MethodElement method,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node, arg);
+  }
+
+  @override
+  R visitTopLevelFunctionSet(
+      Send node,
+      MethodElement function,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node, arg);
+  }
+
+  @override
+  R visitTopLevelGetterSet(
+      SendSet node,
+      FunctionElement 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,
+      ConstantExpression constant,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node, arg);
+  }
+
+  @override
+  R visitUnresolvedSet(
+      Send node,
+      Element element,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node, arg);
+  }
 }
 
 /// Mixin that implements all `visitXIndexSet` methods of [SemanticSendVisitor]
@@ -1696,6 +2183,7 @@
   R visitUnresolvedSuperGetterCompoundIndexSet(
       SendSet node,
       Element element,
+      MethodElement setter,
       Node index,
       AssignmentOperator operator,
       Node rhs,
@@ -1716,6 +2204,17 @@
   }
 
   @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,
@@ -1944,6 +2443,15 @@
   }
 
   @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,
@@ -2361,6 +2869,7 @@
     return bulkHandleNew(node, arg);
   }
 
+  @override
   R visitGenerativeConstructorInvoke(
       NewExpression node,
       ConstructorElement constructor,
@@ -2371,6 +2880,7 @@
     return bulkHandleNew(node, arg);
   }
 
+  @override
   R visitRedirectingGenerativeConstructorInvoke(
       NewExpression node,
       ConstructorElement constructor,
@@ -2381,6 +2891,7 @@
     return bulkHandleNew(node, arg);
   }
 
+  @override
   R visitFactoryConstructorInvoke(
       NewExpression node,
       ConstructorElement constructor,
@@ -2391,6 +2902,7 @@
     return bulkHandleNew(node, arg);
   }
 
+  @override
   R visitRedirectingFactoryConstructorInvoke(
       NewExpression node,
       ConstructorElement constructor,
@@ -2953,7 +3465,7 @@
   }
 
   @override
-  R errorClassTypeLiteralSet(
+  R visitClassTypeLiteralSet(
       SendSet node,
       ConstantExpression constant,
       Node rhs,
@@ -2963,7 +3475,7 @@
   }
 
   @override
-  R errorDynamicTypeLiteralSet(
+  R visitDynamicTypeLiteralSet(
       SendSet node,
       ConstantExpression constant,
       Node rhs,
@@ -2973,7 +3485,7 @@
   }
 
   @override
-  R errorFinalLocalVariableCompound(
+  R visitFinalLocalVariableCompound(
       Send node,
       LocalVariableElement variable,
       AssignmentOperator operator,
@@ -2984,7 +3496,7 @@
   }
 
   @override
-  R errorFinalLocalVariableSet(
+  R visitFinalLocalVariableSet(
       SendSet node,
       LocalVariableElement variable,
       Node rhs,
@@ -2994,7 +3506,7 @@
   }
 
   @override
-  R errorFinalParameterCompound(
+  R visitFinalParameterCompound(
       Send node,
       ParameterElement parameter,
       AssignmentOperator operator,
@@ -3005,7 +3517,7 @@
   }
 
   @override
-  R errorFinalParameterSet(
+  R visitFinalParameterSet(
       SendSet node,
       ParameterElement parameter,
       Node rhs,
@@ -3015,7 +3527,7 @@
   }
 
   @override
-  R errorFinalStaticFieldCompound(
+  R visitFinalStaticFieldCompound(
       Send node,
       FieldElement field,
       AssignmentOperator operator,
@@ -3026,7 +3538,7 @@
   }
 
   @override
-  R errorFinalStaticFieldSet(
+  R visitFinalStaticFieldSet(
       SendSet node,
       FieldElement field,
       Node rhs,
@@ -3036,7 +3548,17 @@
   }
 
   @override
-  R errorFinalSuperFieldCompound(
+  R visitFinalSuperFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitFinalTopLevelFieldCompound(
       Send node,
       FieldElement field,
       AssignmentOperator operator,
@@ -3047,7 +3569,7 @@
   }
 
   @override
-  R errorFinalSuperFieldSet(
+  R visitFinalTopLevelFieldSet(
       SendSet node,
       FieldElement field,
       Node rhs,
@@ -3057,28 +3579,7 @@
   }
 
   @override
-  R errorFinalTopLevelFieldCompound(
-      Send node,
-      FieldElement field,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R errorFinalTopLevelFieldSet(
-      SendSet node,
-      FieldElement field,
-      Node rhs,
-      A arg) {
-    apply(rhs, arg);
-    return null;
-  }
-
-  @override
-  R errorLocalFunctionCompound(
+  R visitLocalFunctionCompound(
       Send node,
       LocalFunctionElement function,
       AssignmentOperator operator,
@@ -3089,7 +3590,7 @@
   }
 
   @override
-  R errorLocalFunctionPostfix(
+  R visitLocalFunctionPostfix(
       Send node,
       LocalFunctionElement function,
       IncDecOperator operator,
@@ -3098,7 +3599,7 @@
   }
 
   @override
-  R errorLocalFunctionPrefix(
+  R visitLocalFunctionPrefix(
       Send node,
       LocalFunctionElement function,
       IncDecOperator operator,
@@ -3107,7 +3608,7 @@
   }
 
   @override
-  R errorLocalFunctionSet(
+  R visitLocalFunctionSet(
       SendSet node,
       LocalFunctionElement function,
       Node rhs,
@@ -3117,7 +3618,7 @@
   }
 
   @override
-  R errorStaticFunctionSet(
+  R visitStaticFunctionSet(
       Send node,
       MethodElement function,
       Node rhs,
@@ -3127,7 +3628,7 @@
   }
 
   @override
-  R errorStaticGetterSet(
+  R visitStaticGetterSet(
       SendSet node,
       FunctionElement getter,
       Node rhs,
@@ -3137,7 +3638,7 @@
   }
 
   @override
-  R errorStaticSetterGet(
+  R visitStaticSetterGet(
       Send node,
       FunctionElement setter,
       A arg) {
@@ -3145,7 +3646,7 @@
   }
 
   @override
-  R errorStaticSetterInvoke(
+  R visitStaticSetterInvoke(
       Send node,
       FunctionElement setter,
       NodeList arguments,
@@ -3156,7 +3657,7 @@
   }
 
   @override
-  R errorSuperGetterSet(
+  R visitSuperGetterSet(
       SendSet node,
       FunctionElement getter,
       Node rhs,
@@ -3166,7 +3667,7 @@
   }
 
   @override
-  R errorSuperMethodSet(
+  R visitSuperMethodSet(
       Send node,
       MethodElement method,
       Node rhs,
@@ -3176,7 +3677,7 @@
   }
 
   @override
-  R errorSuperSetterGet(
+  R visitSuperSetterGet(
       Send node,
       FunctionElement setter,
       A arg) {
@@ -3184,7 +3685,7 @@
   }
 
   @override
-  R errorSuperSetterInvoke(
+  R visitSuperSetterInvoke(
       Send node,
       FunctionElement setter,
       NodeList arguments,
@@ -3195,7 +3696,7 @@
   }
 
   @override
-  R errorTopLevelFunctionSet(
+  R visitTopLevelFunctionSet(
       Send node,
       MethodElement function,
       Node rhs,
@@ -3205,7 +3706,7 @@
   }
 
   @override
-  R errorTopLevelGetterSet(
+  R visitTopLevelGetterSet(
       SendSet node,
       FunctionElement getter,
       Node rhs,
@@ -3215,7 +3716,7 @@
   }
 
   @override
-  R errorTopLevelSetterGet(
+  R visitTopLevelSetterGet(
       Send node,
       FunctionElement setter,
       A arg) {
@@ -3223,7 +3724,7 @@
   }
 
   @override
-  R errorTopLevelSetterInvoke(
+  R visitTopLevelSetterInvoke(
       Send node,
       FunctionElement setter,
       NodeList arguments,
@@ -3234,7 +3735,7 @@
   }
 
   @override
-  R errorTypeVariableTypeLiteralSet(
+  R visitTypeVariableTypeLiteralSet(
       SendSet node,
       TypeVariableElement element,
       Node rhs,
@@ -3244,7 +3745,7 @@
   }
 
   @override
-  R errorTypedefTypeLiteralSet(
+  R visitTypedefTypeLiteralSet(
       SendSet node,
       ConstantExpression constant,
       Node rhs,
@@ -3314,7 +3815,7 @@
   }
 
   @override
-  R errorClassTypeLiteralCompound(
+  R visitClassTypeLiteralCompound(
       Send node,
       ConstantExpression constant,
       AssignmentOperator operator,
@@ -3344,7 +3845,7 @@
   }
 
   @override
-  R errorClassTypeLiteralPostfix(
+  R visitClassTypeLiteralPostfix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -3353,7 +3854,7 @@
   }
 
   @override
-  R errorClassTypeLiteralPrefix(
+  R visitClassTypeLiteralPrefix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -3409,6 +3910,20 @@
   }
 
   @override
+  R visitIfNotNullDynamicPropertyCompound(
+      Send node,
+      Node receiver,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    apply(receiver, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
   R visitDynamicPropertyGet(
       Send node,
       Node receiver,
@@ -3419,6 +3934,16 @@
   }
 
   @override
+  R visitIfNotNullDynamicPropertyGet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      A arg) {
+    apply(receiver, arg);
+    return null;
+  }
+
+  @override
   R visitDynamicPropertyInvoke(
       Send node,
       Node receiver,
@@ -3431,6 +3956,18 @@
   }
 
   @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,
@@ -3443,6 +3980,18 @@
   }
 
   @override
+  R visitIfNotNullDynamicPropertyPostfix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    apply(receiver, arg);
+    return null;
+  }
+
+  @override
   R visitDynamicPropertyPrefix(
       Send node,
       Node receiver,
@@ -3455,18 +4004,42 @@
   }
 
   @override
+  R visitIfNotNullDynamicPropertyPrefix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    apply(receiver, arg);
+    return null;
+  }
+
+  @override
   R visitDynamicPropertySet(
       SendSet node,
       Node receiver,
       Selector selector,
       Node rhs,
       A arg) {
+    apply(receiver, arg);
     apply(rhs, arg);
     return null;
   }
 
   @override
-  R errorDynamicTypeLiteralCompound(
+  R visitIfNotNullDynamicPropertySet(
+      SendSet node,
+      Node receiver,
+      Selector selector,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitDynamicTypeLiteralCompound(
       Send node,
       ConstantExpression constant,
       AssignmentOperator operator,
@@ -3496,7 +4069,7 @@
   }
 
   @override
-  R errorDynamicTypeLiteralPostfix(
+  R visitDynamicTypeLiteralPostfix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -3505,7 +4078,7 @@
   }
 
   @override
-  R errorDynamicTypeLiteralPrefix(
+  R visitDynamicTypeLiteralPrefix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -3658,6 +4231,17 @@
   }
 
   @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,
@@ -4535,7 +5119,7 @@
   }
 
   @override
-  R errorTypeVariableTypeLiteralCompound(
+  R visitTypeVariableTypeLiteralCompound(
       Send node,
       TypeVariableElement element,
       AssignmentOperator operator,
@@ -4565,7 +5149,7 @@
   }
 
   @override
-  R errorTypeVariableTypeLiteralPostfix(
+  R visitTypeVariableTypeLiteralPostfix(
       Send node,
       TypeVariableElement element,
       IncDecOperator operator,
@@ -4574,7 +5158,7 @@
   }
 
   @override
-  R errorTypeVariableTypeLiteralPrefix(
+  R visitTypeVariableTypeLiteralPrefix(
       Send node,
       TypeVariableElement element,
       IncDecOperator operator,
@@ -4583,7 +5167,7 @@
   }
 
   @override
-  R errorTypedefTypeLiteralCompound(
+  R visitTypedefTypeLiteralCompound(
       Send node,
       ConstantExpression constant,
       AssignmentOperator operator,
@@ -4613,7 +5197,7 @@
   }
 
   @override
-  R errorTypedefTypeLiteralPostfix(
+  R visitTypedefTypeLiteralPostfix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -4622,7 +5206,7 @@
   }
 
   @override
-  R errorTypedefTypeLiteralPrefix(
+  R visitTypedefTypeLiteralPrefix(
       Send node,
       ConstantExpression constant,
       IncDecOperator operator,
@@ -4641,7 +5225,7 @@
   }
 
   @override
-  R errorUnresolvedCompound(
+  R visitUnresolvedCompound(
       Send node,
       Element element,
       AssignmentOperator operator,
@@ -4671,7 +5255,7 @@
   }
 
   @override
-  R errorUnresolvedPostfix(
+  R visitUnresolvedPostfix(
       Send node,
       Element element,
       IncDecOperator operator,
@@ -4680,7 +5264,7 @@
   }
 
   @override
-  R errorUnresolvedPrefix(
+  R visitUnresolvedPrefix(
       Send node,
       Element element,
       IncDecOperator operator,
@@ -4689,7 +5273,7 @@
   }
 
   @override
-  R errorUnresolvedSet(
+  R visitUnresolvedSet(
       Send node,
       Element element,
       Node rhs,
@@ -4736,6 +5320,7 @@
   R visitUnresolvedSuperGetterCompoundIndexSet(
       SendSet node,
       Element element,
+      MethodElement setter,
       Node index,
       AssignmentOperator operator,
       Node rhs,
@@ -4760,6 +5345,19 @@
   }
 
   @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,
@@ -4783,6 +5381,7 @@
   R visitUnresolvedSuperGetterIndexPostfix(
       Send node,
       Element element,
+      MethodElement setter,
       Node index,
       IncDecOperator operator,
       A arg) {
@@ -4803,9 +5402,21 @@
   }
 
   @override
+  R visitUnresolvedSuperIndexPostfix(
+      Send node,
+      Element element,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    apply(index, arg);
+    return null;
+  }
+
+  @override
   R visitUnresolvedSuperGetterIndexPrefix(
       Send node,
       Element element,
+      MethodElement setter,
       Node index,
       IncDecOperator operator,
       A arg) {
@@ -4826,6 +5437,17 @@
   }
 
   @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,
@@ -4873,6 +5495,7 @@
     return null;
   }
 
+  @override
   R visitConstConstructorInvoke(
       NewExpression node,
       ConstructedConstantExpression constant,
@@ -4982,13 +5605,431 @@
   R errorNonConstantConstructorInvoke(
       NewExpression node,
       Element element,
-      InterfaceType type,
+      DartType 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,
+      MethodElement getter,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitUnresolvedTopLevelSetterCompound(
+      Send node,
+      MethodElement 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,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitUnresolvedTopLevelSetterPrefix(
+      Send node,
+      MethodElement 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,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitUnresolvedTopLevelSetterPostfix(
+      Send node,
+      MethodElement 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,
+      FunctionElement method,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperMethodPostfix(
+      Send node,
+      FunctionElement method,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperMethodPrefix(
+      Send node,
+      FunctionElement 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,
+      FunctionElement 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(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitUnresolvedSuperPrefix(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitUnresolvedSuperGetterCompound(
+      Send node, Element element,
+      MethodElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitUnresolvedSuperGetterPostfix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitUnresolvedSuperGetterPrefix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitUnresolvedSuperSetterCompound(
+      Send node, MethodElement getter,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitUnresolvedSuperSetterPostfix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitUnresolvedSuperSetterPrefix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
 }
 
 /// [SemanticDeclarationVisitor] that visits subnodes.
@@ -5463,20 +6504,13 @@
   }
 }
 
-/// Mixin that groups all `visitStaticX` and `visitTopLevelX` method by
-/// delegating calls to `handleStaticX` methods.
+/// 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 handleStaticFieldCompound(
-      Send node,
-      FieldElement field,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg);
-
   R handleStaticFieldGet(
       Send node,
       FieldElement field,
@@ -5489,13 +6523,6 @@
       CallStructure callStructure,
       A arg);
 
-  R handleStaticFieldPostfixPrefix(
-      Send node,
-      FieldElement field,
-      IncDecOperator operator,
-      A arg,
-      {bool isPrefix});
-
   R handleStaticFieldSet(
       SendSet node,
       FieldElement field,
@@ -5526,6 +6553,12 @@
       FunctionElement getter,
       A arg);
 
+  R handleStaticGetterSet(
+      Send node,
+      FunctionElement getter,
+      Node rhs,
+      A arg);
+
   R handleStaticGetterInvoke(
       Send node,
       FunctionElement getter,
@@ -5533,53 +6566,35 @@
       CallStructure callStructure,
       A arg);
 
-  R handleStaticGetterSetterCompound(
-      Send node,
-      FunctionElement getter,
+  R handleStaticSetterGet(
+      SendSet node,
       FunctionElement setter,
-      AssignmentOperator operator,
-      Node rhs,
       A arg);
 
-  R handleStaticGetterSetterPostfixPrefix(
-      Send node,
-      FunctionElement getter,
-      FunctionElement setter,
-      IncDecOperator operator,
-      A arg,
-      {bool isPrefix});
-
-  R handleStaticMethodSetterCompound(
-      Send node,
-      FunctionElement method,
-      FunctionElement setter,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg);
-
-  R handleStaticMethodSetterPostfixPrefix(
-      Send node,
-      FunctionElement getter,
-      FunctionElement setter,
-      IncDecOperator operator,
-      A arg,
-      {bool isPrefix});
-
   R handleStaticSetterSet(
       SendSet node,
       FunctionElement setter,
       Node rhs,
       A arg);
 
-  @override
-  R visitStaticFieldCompound(
+  R handleStaticSetterInvoke(
       Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      CallStructure callStructure,
+      A arg);
+
+  R handleFinalStaticFieldSet(
+      SendSet node,
       FieldElement field,
-      AssignmentOperator operator,
       Node rhs,
-      A arg) {
-    return handleStaticFieldCompound(node, field, operator, rhs, arg);
-  }
+      A arg);
+
+  R handleStaticFunctionSet(
+      SendSet node,
+      MethodElement function,
+      Node rhs,
+      A arg);
 
   @override
   R visitStaticFieldGet(
@@ -5600,26 +6615,6 @@
   }
 
   @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 visitStaticFieldSet(
       SendSet node,
       FieldElement field,
@@ -5678,6 +6673,336 @@
   }
 
   @override
+  R visitStaticSetterSet(
+      SendSet node,
+      FunctionElement 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,
+      FunctionElement getter,
+      A arg) {
+    return handleStaticGetterGet(node, getter, arg);
+  }
+
+  @override
+  R visitTopLevelGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg) {
+    return handleStaticGetterSet(node, getter, rhs, arg);
+  }
+
+  @override
+  R visitTopLevelGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      CallStructure callStructure,
+      A arg) {
+    return handleStaticGetterInvoke(
+        node, getter, arguments, callStructure, arg);
+  }
+
+  @override
+  R visitTopLevelSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg) {
+    return handleStaticSetterSet(node, setter, rhs, arg);
+  }
+
+  @override
+  R visitStaticSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      CallStructure callStructure,
+      A arg) {
+    return handleStaticSetterInvoke(
+        node, setter, arguments, callStructure, arg);
+  }
+
+  @override
+  R visitTopLevelSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      CallStructure callStructure,
+      A arg) {
+    return handleStaticSetterInvoke(
+        node, setter, arguments, callStructure, arg);
+  }
+
+  @override
+  R visitStaticSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg) {
+    return handleStaticSetterGet(node, setter, arg);
+  }
+
+  @override
+  R visitStaticGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg) {
+    return handleStaticGetterSet(node, getter, rhs, arg);
+  }
+
+  @override
+  R visitTopLevelSetterGet(
+      Send node,
+      FunctionElement 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(
+      Send node,
+      MethodElement function,
+      Node rhs,
+      A arg) {
+    return handleStaticFunctionSet(node, function, rhs, arg);
+  }
+
+  @override
+  R visitTopLevelFunctionSet(
+      Send 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,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  R handleStaticGetterSetterPostfixPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  R handleStaticMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  R handleStaticMethodSetterPostfixPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement 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,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  R handleUnresolvedStaticGetterPostfixPrefix(
+      Send node,
+      Element element,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  R handleUnresolvedStaticSetterCompound(
+      Send node,
+      FunctionElement getter,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  R handleUnresolvedStaticSetterPostfixPrefix(
+      Send node,
+      FunctionElement 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,
       FunctionElement getter,
@@ -5746,15 +7071,6 @@
   }
 
   @override
-  R visitStaticSetterSet(
-      SendSet node,
-      FunctionElement setter,
-      Node rhs,
-      A arg) {
-    return handleStaticSetterSet(node, setter, rhs, arg);
-  }
-
-  @override
   R visitTopLevelFieldCompound(
       Send node,
       FieldElement field,
@@ -5765,24 +7081,6 @@
   }
 
   @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 visitTopLevelFieldPostfix(
       Send node,
       FieldElement field,
@@ -5803,64 +7101,6 @@
   }
 
   @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,
-      FunctionElement getter,
-      A arg) {
-    return handleStaticGetterGet(node, getter, arg);
-  }
-
-  @override
-  R visitTopLevelGetterInvoke(
-      Send node,
-      FunctionElement getter,
-      NodeList arguments,
-      CallStructure callStructure,
-      A arg) {
-    return handleStaticGetterInvoke(
-        node, getter, arguments, callStructure, arg);
-  }
-
-  @override
   R visitTopLevelGetterSetterCompound(
       Send node,
       FunctionElement getter,
@@ -5929,29 +7169,143 @@
   }
 
   @override
-  R visitTopLevelSetterSet(
-      SendSet node,
-      FunctionElement setter,
+  R visitFinalStaticFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
       Node rhs,
       A arg) {
-    return handleStaticSetterSet(node, setter, rhs, 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,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return handleUnresolvedStaticGetterCompound(
+        node, element, setter, operator, rhs, arg);
+  }
+
+  @override
+  R visitUnresolvedStaticGetterPostfix(
+      Send node,
+      Element element,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleUnresolvedStaticGetterPostfixPrefix(
+        node, element, setter, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitUnresolvedStaticGetterPrefix(
+      Send node,
+      Element element,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleUnresolvedStaticGetterPostfixPrefix(
+        node, element, setter, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitUnresolvedStaticSetterCompound(
+      Send node,
+      FunctionElement getter,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return handleUnresolvedStaticSetterCompound(
+        node, getter, element, operator, rhs, arg);
+  }
+
+  @override
+  R visitUnresolvedStaticSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return handleUnresolvedStaticSetterPostfixPrefix(
+        node, getter, element, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitUnresolvedStaticSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return handleUnresolvedStaticSetterPostfixPrefix(
+        node, getter, element, operator, arg, isPrefix: true);
   }
 }
 
-/// Mixin that groups all `visitLocalX` and `visitParameterX` method by
-/// delegating calls to `handleLocalX` methods.
+/// 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 handleLocalCompound(
-      Send node,
-      LocalElement element,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg);
-
   R handleLocalGet(
       Send node,
       LocalElement element,
@@ -5964,19 +7318,18 @@
       CallStructure callStructure,
       A arg);
 
-  R handleLocalPostfixPrefix(
-      Send node,
-      LocalElement element,
-      IncDecOperator operator,
-      A arg,
-      {bool isPrefix});
-
   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,
@@ -5996,16 +7349,6 @@
   }
 
   @override
-  R visitLocalVariableCompound(
-      Send node,
-      LocalVariableElement variable,
-      AssignmentOperator operator,
-      Node rhs,
-      A arg) {
-    return handleLocalCompound(node, variable, operator, rhs, arg);
-  }
-
-  @override
   R visitLocalVariableGet(
       Send node,
       LocalVariableElement variable,
@@ -6024,6 +7367,101 @@
   }
 
   @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,
@@ -6044,15 +7482,6 @@
   }
 
   @override
-  R visitLocalVariableSet(
-      SendSet node,
-      LocalVariableElement variable,
-      Node rhs,
-      A arg) {
-    return handleLocalSet(node, variable, rhs, arg);
-  }
-
-  @override
   R visitParameterCompound(
       Send node,
       ParameterElement parameter,
@@ -6063,24 +7492,6 @@
   }
 
   @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 visitParameterPostfix(
       Send node,
       ParameterElement parameter,
@@ -6099,15 +7510,6 @@
     return handleLocalPostfixPrefix(
         node, parameter, operator, arg, isPrefix: true);
   }
-
-  @override
-  R visitParameterSet(
-      SendSet node,
-      ParameterElement parameter,
-      Node rhs,
-      A arg) {
-    return handleLocalSet(node, parameter, rhs, arg);
-  }
 }
 
 /// Mixin that groups all `visitConstantX` and `visitXTypeLiteralY` methods for
@@ -6210,23 +7612,14 @@
   }
 }
 
-/// Mixin that groups all `visitDynamicPropertyX` and `visitThisPropertyY`
-/// methods for by delegating calls to `handleDynamicX` methods, providing
-/// `null` as the receiver for the this properties.
+/// 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 handleDynamicCompound(
-      Send node,
-      Node receiver,
-      AssignmentOperator operator,
-      Node rhs,
-      Selector getterSelector,
-      Selector setterSelector,
-      A arg);
-
   R handleDynamicGet(
       Send node,
       Node receiver,
@@ -6240,6 +7633,116 @@
       Selector selector,
       A arg);
 
+  R handleDynamicSet(
+      SendSet node,
+      Node receiver,
+      Selector selector,
+      Node rhs,
+      A arg);
+
+  @override
+  R visitDynamicPropertyGet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      A arg) {
+    return handleDynamicGet(node, receiver, selector, arg);
+  }
+
+  @override
+  R visitIfNotNullDynamicPropertyGet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      A arg) {
+    // TODO(johnniwinther): should these redirect to handleDynamicX?
+    return handleDynamicGet(node, receiver, selector, 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,
+      Selector selector,
+      Node rhs,
+      A arg) {
+    return handleDynamicSet(node, receiver, selector, rhs, arg);
+  }
+
+  @override
+  R visitIfNotNullDynamicPropertySet(
+      SendSet node,
+      Node receiver,
+      Selector selector,
+      Node rhs,
+      A arg) {
+    return handleDynamicSet(node, receiver, selector, rhs, arg);
+  }
+
+  @override
+  R visitThisPropertyGet(
+      Send node,
+      Selector selector,
+      A arg) {
+    return handleDynamicGet(node, null, selector, arg);
+  }
+
+  @override
+  R visitThisPropertyInvoke(
+      Send node,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleDynamicInvoke(node, null, arguments, selector, arg);
+  }
+
+  @override
+  R visitThisPropertySet(
+      SendSet node,
+      Selector selector,
+      Node rhs,
+      A arg) {
+    return handleDynamicSet(node, null, selector, 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,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg);
+
   R handleDynamicPostfixPrefix(
       Send node,
       Node receiver,
@@ -6249,13 +7752,6 @@
       A arg,
       {bool isPrefix});
 
-  R handleDynamicSet(
-      SendSet node,
-      Node receiver,
-      Selector selector,
-      Node rhs,
-      A arg);
-
   R handleDynamicIndexPostfixPrefix(
       Send node,
       Node receiver,
@@ -6278,22 +7774,16 @@
   }
 
   @override
-  R visitDynamicPropertyGet(
+  R visitIfNotNullDynamicPropertyCompound(
       Send node,
       Node receiver,
-      Selector selector,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
       A arg) {
-    return handleDynamicGet(node, receiver, selector, arg);
-  }
-
-  @override
-  R visitDynamicPropertyInvoke(
-      Send node,
-      Node receiver,
-      NodeList arguments,
-      Selector selector,
-      A arg) {
-    return handleDynamicInvoke(node, receiver, arguments, selector, arg);
+    return handleDynamicCompound(
+        node, receiver, operator, rhs, getterSelector, setterSelector, arg);
   }
 
   @override
@@ -6310,6 +7800,19 @@
   }
 
   @override
+  R visitIfNotNullDynamicPropertyPostfix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicPostfixPrefix(
+        node, receiver, operator,
+        getterSelector, setterSelector, arg, isPrefix: false);
+  }
+
+  @override
   R visitDynamicPropertyPrefix(
       Send node,
       Node receiver,
@@ -6323,13 +7826,16 @@
   }
 
   @override
-  R visitDynamicPropertySet(
-      SendSet node,
+  R visitIfNotNullDynamicPropertyPrefix(
+      Send node,
       Node receiver,
-      Selector selector,
-      Node rhs,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
       A arg) {
-    return handleDynamicSet(node, receiver, selector, rhs, arg);
+    return handleDynamicPostfixPrefix(
+        node, receiver, operator,
+        getterSelector, setterSelector, arg, isPrefix: true);
   }
 
   @override
@@ -6345,23 +7851,6 @@
   }
 
   @override
-  R visitThisPropertyGet(
-      Send node,
-      Selector selector,
-      A arg) {
-    return handleDynamicGet(node, null, selector, arg);
-  }
-
-  @override
-  R visitThisPropertyInvoke(
-      Send node,
-      NodeList arguments,
-      Selector selector,
-      A arg) {
-    return handleDynamicInvoke(node, null, arguments, selector, arg);
-  }
-
-  @override
   R visitThisPropertyPostfix(
       Send node,
       IncDecOperator operator,
@@ -6386,15 +7875,6 @@
   }
 
   @override
-  R visitThisPropertySet(
-      SendSet node,
-      Selector selector,
-      Node rhs,
-      A arg) {
-    return handleDynamicSet(node, null, selector, rhs, arg);
-  }
-
-  @override
   R visitIndexPostfix(
       Send node,
       Node receiver,
@@ -6417,6 +7897,2145 @@
   }
 }
 
+/// 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,
+      CompoundRhs rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg);
+
+  R visitDynamicPropertyCompound(
+      Send node,
+      Node receiver,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicCompounds(
+        node,
+        receiver,
+        new AssignmentCompound(operator, rhs),
+        getterSelector,
+        setterSelector,
+        arg);
+  }
+
+  R visitIfNotNullDynamicPropertyCompound(
+      Send node,
+      Node receiver,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicCompounds(
+        node,
+        receiver,
+        new AssignmentCompound(operator, rhs),
+        getterSelector,
+        setterSelector,
+        arg);
+  }
+
+  @override
+  R visitThisPropertyCompound(
+      Send node,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicCompounds(
+        node,
+        null,
+        new AssignmentCompound(operator, rhs),
+        getterSelector,
+        setterSelector,
+        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,
+      FunctionElement getter,
+      FunctionElement 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,
+      FunctionElement 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,
+      FunctionElement getter,
+      FunctionElement 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,
+      FunctionElement 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,
+      FunctionElement getter,
+      FunctionElement 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,
+      FunctionElement 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,
+      FunctionElement 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,
+      FunctionElement 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,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicCompounds(
+        node,
+        receiver,
+        new IncDecCompound(CompoundKind.PREFIX, operator),
+        getterSelector,
+        setterSelector,
+        arg);
+  }
+
+  R visitIfNotNullDynamicPropertyPrefix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicCompounds(
+        node,
+        receiver,
+        new IncDecCompound(CompoundKind.PREFIX, operator),
+        getterSelector,
+        setterSelector,
+        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,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicCompounds(
+        node,
+        null,
+        new IncDecCompound(CompoundKind.PREFIX, operator),
+        getterSelector,
+        setterSelector,
+        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,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticCompounds(
+        node,
+        getter, CompoundGetter.GETTER,
+        setter, CompoundSetter.SETTER,
+        new IncDecCompound(CompoundKind.PREFIX, operator),
+        arg);
+  }
+
+
+  R visitStaticMethodSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement 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,
+      FunctionElement getter,
+      FunctionElement 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,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticCompounds(
+        node,
+        method, CompoundGetter.METHOD,
+        setter, CompoundSetter.SETTER,
+        new IncDecCompound(CompoundKind.PREFIX, operator),
+        arg);
+  }
+
+  @override
+  R visitSuperFieldPrefix(
+      Send 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(
+      Send 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(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperCompounds(
+        node,
+        field, CompoundGetter.FIELD,
+        setter, CompoundSetter.SETTER,
+        new IncDecCompound(CompoundKind.PREFIX, operator),
+        arg);
+  }
+
+
+  R visitSuperGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperCompounds(
+        node,
+        getter, CompoundGetter.GETTER,
+        setter, CompoundSetter.SETTER,
+        new IncDecCompound(CompoundKind.PREFIX, operator),
+        arg);
+  }
+
+  @override
+  R visitSuperGetterFieldPrefix(
+      Send node,
+      FunctionElement 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(
+      Send node,
+      FunctionElement method,
+      FunctionElement 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,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicCompounds(
+        node,
+        receiver,
+        new IncDecCompound(CompoundKind.POSTFIX, operator),
+        getterSelector,
+        setterSelector,
+        arg);
+  }
+
+  @override
+  R visitIfNotNullDynamicPropertyPostfix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicCompounds(
+        node,
+        receiver,
+        new IncDecCompound(CompoundKind.POSTFIX, operator),
+        getterSelector,
+        setterSelector,
+        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,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicCompounds(
+        node,
+        null,
+        new IncDecCompound(CompoundKind.POSTFIX, operator),
+        getterSelector,
+        setterSelector,
+        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,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticCompounds(
+        node,
+        getter, CompoundGetter.GETTER,
+        setter, CompoundSetter.SETTER,
+        new IncDecCompound(CompoundKind.POSTFIX, operator),
+        arg);
+  }
+
+
+  R visitStaticMethodSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement 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,
+      FunctionElement getter,
+      FunctionElement 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,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticCompounds(
+        node,
+        method, CompoundGetter.METHOD,
+        setter, CompoundSetter.SETTER,
+        new IncDecCompound(CompoundKind.POSTFIX, operator),
+        arg);
+  }
+
+  @override
+  R visitSuperFieldPostfix(
+      Send 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(
+      Send 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(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperCompounds(
+        node,
+        field, CompoundGetter.FIELD,
+        setter, CompoundSetter.SETTER,
+        new IncDecCompound(CompoundKind.POSTFIX, operator),
+        arg);
+  }
+
+
+  R visitSuperGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperCompounds(
+        node,
+        getter, CompoundGetter.GETTER,
+        setter, CompoundSetter.SETTER,
+        new IncDecCompound(CompoundKind.POSTFIX, operator),
+        arg);
+  }
+
+  @override
+  R visitSuperGetterFieldPostfix(
+      Send node,
+      FunctionElement 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(
+      Send node,
+      FunctionElement method,
+      FunctionElement 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,
+      MethodElement 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,
+      MethodElement 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,
+      Element 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,
+      MethodElement 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,
+      MethodElement 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,
+      Element 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,
+      MethodElement 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,
+      MethodElement 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,
+      Element 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,
+      FunctionElement 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,
+      FunctionElement 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,
+      FunctionElement 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(
+      Send 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(
+      Send 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(
+      Send node, Element element,
+      MethodElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return handleSuperCompounds(
+        node,
+        element,
+        CompoundGetter.UNRESOLVED,
+        setter,
+        CompoundSetter.SETTER,
+        new AssignmentCompound(operator, rhs),
+        arg);
+  }
+
+  @override
+  R visitUnresolvedSuperGetterPostfix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperCompounds(
+        node,
+        element,
+        CompoundGetter.UNRESOLVED,
+        setter,
+        CompoundSetter.SETTER,
+        new IncDecCompound(CompoundKind.POSTFIX, operator),
+        arg);
+  }
+
+  @override
+  R visitUnresolvedSuperGetterPrefix(
+      Send node,
+      Element element,
+      MethodElement 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,
+      MethodElement 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(
+      Send node,
+      MethodElement 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(
+      Send node,
+      MethodElement 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 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,
+      FunctionElement indexFunction,
+      FunctionElement 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,
+      FunctionElement indexFunction,
+      FunctionElement 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,
+      FunctionElement indexFunction,
+      FunctionElement 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(
+      Send 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(
+      Send node,
+      FunctionElement 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(
+      Send 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(
+      Send 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(
+      Send 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(
+      Send 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(
+      Send 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);
+  }
+}
+
+
+
 /// Mixin that groups all `visitSuperXPrefix`, `visitSuperXPostfix` methods by
 /// delegating calls to `handleSuperXPostfixPrefix` methods.
 ///
@@ -6476,6 +10095,7 @@
   R handleUnresolvedSuperGetterIndexPostfixPrefix(
       Send node,
       Element element,
+      MethodElement setter,
       Node index,
       IncDecOperator operator,
       A arg,
@@ -6490,6 +10110,51 @@
       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,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
   @override
   R visitSuperFieldFieldPostfix(
       Send node,
@@ -6650,22 +10315,24 @@
   R visitUnresolvedSuperGetterIndexPostfix(
       Send node,
       Element element,
+      MethodElement setter,
       Node index,
       IncDecOperator operator,
       A arg) {
     return handleUnresolvedSuperGetterIndexPostfixPrefix(
-        node, element, index, operator, arg, isPrefix: false);
+        node, element, setter, index, operator, arg, isPrefix: false);
   }
 
   @override
   R visitUnresolvedSuperGetterIndexPrefix(
       Send node,
       Element element,
+      MethodElement setter,
       Node index,
       IncDecOperator operator,
       A arg) {
     return handleUnresolvedSuperGetterIndexPostfixPrefix(
-        node, element, index, operator, arg, isPrefix: true);
+        node, element, setter, index, operator, arg, isPrefix: true);
   }
 
   @override
@@ -6691,6 +10358,132 @@
     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(
+      Send 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(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleUnresolvedSuperGetterPostfixPrefix(
+        node, element, setter, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitUnresolvedSuperGetterPrefix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleUnresolvedSuperGetterPostfixPrefix(
+        node, element, setter, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitUnresolvedSuperSetterPostfix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return handleUnresolvedSuperSetterPostfixPrefix(
+        node, getter, element, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitUnresolvedSuperSetterPrefix(
+      Send node,
+      MethodElement 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
@@ -6720,6 +10513,7 @@
         node, constructor, type, arguments, callStructure, arg);
   }
 
+  @override
   R visitRedirectingGenerativeConstructorInvoke(
       NewExpression node,
       ConstructorElement constructor,
@@ -6731,6 +10525,7 @@
         node, constructor, type, arguments, callStructure, arg);
   }
 
+  @override
   R visitFactoryConstructorInvoke(
       NewExpression node,
       ConstructorElement constructor,
@@ -6742,6 +10537,7 @@
         node, constructor, type, arguments, callStructure, arg);
   }
 
+  @override
   R visitRedirectingFactoryConstructorInvoke(
       NewExpression node,
       ConstructorElement constructor,
@@ -6755,6 +10551,7 @@
         node, constructor, type, arguments, callStructure, arg);
   }
 
+  @override
   R visitUnresolvedConstructorInvoke(
       NewExpression node,
       Element constructor,
@@ -6766,6 +10563,7 @@
         node, constructor, type, arguments, selector.callStructure, arg);
   }
 
+  @override
   R visitUnresolvedClassConstructorInvoke(
       NewExpression node,
       Element element,
@@ -6777,6 +10575,7 @@
         node, element, type, arguments, selector.callStructure, arg);
   }
 
+  @override
   R visitAbstractClassConstructorInvoke(
       NewExpression node,
       ConstructorElement constructor,
@@ -6787,6 +10586,8 @@
     return handleConstructorInvoke(
         node, constructor, type, arguments, callStructure, arg);
   }
+
+  @override
   R visitUnresolvedRedirectingFactoryConstructorInvoke(
       NewExpression node,
       ConstructorElement constructor,
diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
index f4bbaa5..a706f1c 100644
--- a/pkg/compiler/lib/src/resolution/send_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/send_resolver.dart
@@ -28,28 +28,125 @@
 
   internalError(Spannable spannable, String message);
 
-  AccessSemantics handleStaticallyResolvedAccess(Send node,
-                                                 Element element,
-                                                 Element getter) {
+  AccessSemantics handleCompoundErroneousSetterAccess(
+      Send node,
+      Element setter,
+      Element getter) {
+    assert(invariant(node, Elements.isUnresolved(setter),
+        message: "Unexpected erreneous compound setter: $setter."));
+    if (getter.isStatic) {
+      if (getter.isGetter) {
+        return new CompoundAccessSemantics(
+            CompoundAccessKind.UNRESOLVED_STATIC_SETTER, getter, setter);
+      } else if (getter.isField) {
+        // TODO(johnniwinther): Handle const field separately.
+        assert(invariant(node, getter.isFinal || getter.isConst,
+            message: "Field expected to be final or const."));
+        return new StaticAccess.finalStaticField(getter);
+      } else if (getter.isFunction) {
+        return new StaticAccess.staticMethod(getter);
+      } else {
+        return internalError(node,
+            "Unexpected erroneous static compound: getter=$getter");
+      }
+    } else if (getter.isTopLevel) {
+      if (getter.isGetter) {
+        return new CompoundAccessSemantics(
+            CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER, getter, setter);
+      } else if (getter.isField) {
+        // TODO(johnniwinther): Handle const field separately.
+        assert(invariant(node, getter.isFinal || getter.isConst,
+            message: "Field expected to be final or const."));
+        return new StaticAccess.finalTopLevelField(getter);
+      } else if (getter.isFunction) {
+        return new StaticAccess.topLevelMethod(getter);
+      } else {
+        return internalError(node,
+            "Unexpected erroneous top level compound: getter=$getter");
+      }
+    } else if (getter.isParameter) {
+      assert(invariant(node, getter.isFinal,
+          message: "Parameter expected to be final."));
+      return new StaticAccess.finalParameter(getter);
+    } else if (getter.isLocal) {
+      if (getter.isVariable) {
+        // TODO(johnniwinther): Handle const variable separately.
+        assert(invariant(node, getter.isFinal || getter.isConst,
+            message: "Variable expected to be final or const."));
+        return new StaticAccess.finalLocalVariable(getter);
+      } else if (getter.isFunction) {
+        return new StaticAccess.localFunction(getter);
+      } else {
+        return internalError(node,
+            "Unexpected erroneous local compound: getter=$getter");
+      }
+    } else if (getter.isErroneous) {
+      return new StaticAccess.unresolved(getter);
+    } else {
+      return internalError(node,
+          "Unexpected erroneous compound: getter=$getter");
+    }
+  }
+
+  AccessSemantics handleStaticallyResolvedAccess(
+      Send node,
+      Element element,
+      Element getter,
+      {bool isCompound}) {
+    if (element == null) {
+      assert(invariant(node, isCompound, message:
+        "Non-compound static access without element."));
+      assert(invariant(node, getter != null, message:
+        "Compound static access without element."));
+      return handleCompoundErroneousSetterAccess(node, element, getter);
+    }
     if (element.isErroneous) {
+      if (isCompound) {
+        return handleCompoundErroneousSetterAccess(node, element, getter);
+      }
       return new StaticAccess.unresolved(element);
     } else if (element.isParameter) {
-      return new StaticAccess.parameter(element);
+      if (element.isFinal) {
+        return new StaticAccess.finalParameter(element);
+      } else {
+        return new StaticAccess.parameter(element);
+      }
     } else if (element.isLocal) {
       if (element.isFunction) {
         return new StaticAccess.localFunction(element);
+      } else if (element.isFinal || element.isConst) {
+        return new StaticAccess.finalLocalVariable(element);
       } else {
         return new StaticAccess.localVariable(element);
       }
     } else if (element.isStatic) {
       if (element.isField) {
+        if (element.isFinal || element.isConst) {
+          // TODO(johnniwinther): Handle const field separately.
+          return new StaticAccess.finalStaticField(element);
+        }
         return new StaticAccess.staticField(element);
       } else if (element.isGetter) {
+        if (isCompound) {
+          return new CompoundAccessSemantics(
+              CompoundAccessKind.UNRESOLVED_STATIC_SETTER, element, null);
+        }
         return new StaticAccess.staticGetter(element);
       } else if (element.isSetter) {
         if (getter != null) {
           CompoundAccessKind accessKind;
-          if (getter.isGetter) {
+          if (getter.isErroneous) {
+            accessKind = CompoundAccessKind.UNRESOLVED_STATIC_GETTER;
+          } else if (getter.isAbstractField) {
+            AbstractFieldElement abstractField = getter;
+            if (abstractField.getter == null) {
+              accessKind = CompoundAccessKind.UNRESOLVED_STATIC_GETTER;
+            } else {
+              // TODO(johnniwinther): This might be dead code.
+              getter = abstractField.getter;
+              accessKind = CompoundAccessKind.STATIC_GETTER_SETTER;
+            }
+          } else if (getter.isGetter) {
             accessKind = CompoundAccessKind.STATIC_GETTER_SETTER;
           } else {
             accessKind = CompoundAccessKind.STATIC_METHOD_SETTER;
@@ -64,13 +161,28 @@
       }
     } else if (element.isTopLevel) {
       if (element.isField) {
+        if (element.isFinal || element.isConst) {
+          // TODO(johnniwinther): Handle const field separately.
+          return new StaticAccess.finalTopLevelField(element);
+        }
         return new StaticAccess.topLevelField(element);
       } else if (element.isGetter) {
         return new StaticAccess.topLevelGetter(element);
       } else if (element.isSetter) {
         if (getter != null) {
           CompoundAccessKind accessKind;
-          if (getter.isGetter) {
+          if (getter.isErroneous) {
+            accessKind = CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER;
+          } else if (getter.isAbstractField) {
+            AbstractFieldElement abstractField = getter;
+            if (abstractField.getter == null) {
+              accessKind = CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER;
+            } else {
+              // TODO(johnniwinther): This might be dead code.
+              getter = abstractField.getter;
+              accessKind = CompoundAccessKind.TOPLEVEL_GETTER_SETTER;
+            }
+          } else if (getter.isGetter) {
             accessKind = CompoundAccessKind.TOPLEVEL_GETTER_SETTER;
           } else {
             accessKind = CompoundAccessKind.TOPLEVEL_METHOD_SETTER;
@@ -90,12 +202,13 @@
   }
 
   SendStructure computeSendStructure(Send node) {
+    SendStructure sendStructure = elements.getSendStructure(node);
+    if (sendStructure != null) {
+      return sendStructure;
+    }
+
     if (elements.isAssert(node)) {
-      if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) {
-        return const AssertStructure();
-      } else {
-        return const InvalidAssertStructure();
-      }
+      return internalError(node, "Unexpected assert.");
     }
 
     AssignmentOperator assignmentOperator;
@@ -106,18 +219,15 @@
     if (node.isOperator) {
       String operatorText = node.selector.asOperator().source;
       if (operatorText == 'is') {
-        if (node.isIsNotCheck) {
-          return new IsNotStructure(
-              elements.getType(node.arguments.single.asSend().receiver));
-        } else {
-          return new IsStructure(elements.getType(node.arguments.single));
-        }
+        return internalError(node, "Unexpected is test.");
       } else if (operatorText == 'as') {
-        return new AsStructure(elements.getType(node.arguments.single));
+        return internalError(node, "Unexpected as cast.");
       } else if (operatorText == '&&') {
-        return const LogicalAndStructure();
+        return internalError(node, "Unexpected logical and.");
       } else if (operatorText == '||') {
-        return const LogicalOrStructure();
+        return internalError(node, "Unexpected logical or.");
+      } else if (operatorText == '??') {
+        return internalError(node, "Unexpected if-null.");
       }
     }
 
@@ -215,8 +325,7 @@
     }
     AccessSemantics semantics = computeAccessSemantics(
         node,
-        isGetOrSet: kind == SendStructureKind.GET ||
-                    kind == SendStructureKind.SET,
+        isSet: kind == SendStructureKind.SET,
         isInvoke: kind == SendStructureKind.INVOKE,
         isCompound: kind == SendStructureKind.COMPOUND ||
                     kind == SendStructureKind.COMPOUND_INDEX_SET ||
@@ -248,18 +357,17 @@
         }
         return new InvokeStructure(semantics, selector);
       case SendStructureKind.UNARY:
-        return new UnaryStructure(semantics, unaryOperator, selector);
+        return internalError(node, "Unexpected unary.");
       case SendStructureKind.NOT:
-        assert(selector == null);
-        return new NotStructure(semantics, selector);
+        return internalError(node, "Unexpected not.");
       case SendStructureKind.BINARY:
-        return new BinaryStructure(semantics, binaryOperator, selector);
+        return internalError(node, "Unexpected binary.");
       case SendStructureKind.INDEX:
-        return new IndexStructure(semantics, selector);
+        return internalError(node, "Unexpected index.");
       case SendStructureKind.EQ:
-        return new EqualsStructure(semantics, selector);
+        return internalError(node, "Unexpected equals.");
       case SendStructureKind.NOT_EQ:
-        return new NotEqualsStructure(semantics, selector);
+        return internalError(node, "Unexpected not equals.");
       case SendStructureKind.COMPOUND:
         Selector getterSelector =
             elements.getGetterSelectorInComplexSendSet(node);
@@ -314,7 +422,7 @@
   }
 
   AccessSemantics computeAccessSemantics(Send node,
-                                         {bool isGetOrSet: false,
+                                         {bool isSet: false,
                                           bool isInvoke: false,
                                           bool isCompound: false}) {
     Element element = elements[node];
@@ -325,7 +433,7 @@
       // but not compile-time constants and should have their own
       // [DeferredConstantExpression] class.
       ConstantExpression constant = elements.getConstant(
-          isInvoke ? node.selector : node);
+          isInvoke || isSet || isCompound ? node.selector : node);
       switch (dartType.kind) {
         case TypeKind.INTERFACE:
           return new ConstantAccess.classTypeLiteral(constant);
@@ -344,8 +452,18 @@
           if (Elements.isUnresolved(getter)) {
             // TODO(johnniwinther): Ensure that [getter] is not null. This
             // happens in the case of missing super getter.
-            return new CompoundAccessSemantics(
-                CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, element);
+            return new StaticAccess.unresolvedSuper(element);
+          } else if (getter.isField) {
+            assert(invariant(node, getter.isFinal,
+                message: "Super field expected to be final."));
+            return new StaticAccess.superFinalField(getter);
+          } else if (getter.isFunction) {
+            if (node.isIndex) {
+              return new CompoundAccessSemantics(
+                  CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, element);
+            } else {
+              return new StaticAccess.superMethod(getter);
+            }
           } else {
             return new CompoundAccessSemantics(
                 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, element);
@@ -370,6 +488,8 @@
                "Unsupported super call: $node : $element/$getter.");
           }
           return new CompoundAccessSemantics(accessKind, getter, element);
+        } else if (element.isFinal) {
+          return new StaticAccess.superFinalField(element);
         }
         return new StaticAccess.superField(element);
       } else if (element.isGetter) {
@@ -393,7 +513,11 @@
       } else {
         return new StaticAccess.superMethod(element);
       }
-    } else if (node.isOperator) {
+    } else if (node.isOperator || node.isConditional) {
+      // Conditional sends (e?.x) are treated as dynamic property reads because
+      // they are equivalent to do ((a) => a == null ? null : a.x)(e). If `e` is
+      // a type `A`, this is equivalent to write `(A).x`.
+      // TODO(johnniwinther): maybe add DynamicAccess.conditionalDynamicProperty
       return new DynamicAccess.dynamicProperty(node.receiver);
     } else if (Elements.isClosureSend(node, element)) {
       if (element == null) {
@@ -405,32 +529,38 @@
       } else if (Elements.isErroneous(element)) {
         return new StaticAccess.unresolved(element);
       } else {
-        return handleStaticallyResolvedAccess(node, element, getter);
+        return handleStaticallyResolvedAccess(
+            node, element, getter, isCompound: isCompound);
       }
     } else {
-      if (Elements.isErroneous(element)) {
-        return new StaticAccess.unresolved(element);
-      } else if (isCompound && Elements.isErroneous(getter)) {
-        return new StaticAccess.unresolved(getter);
-      } else if (element == null || element.isInstanceMember) {
+      bool isDynamicAccess(Element e) => e == null || e.isInstanceMember;
+
+      if (isDynamicAccess(element) &&
+           (!isCompound || isDynamicAccess(getter))) {
         if (node.receiver == null || node.receiver.isThis()) {
           return new AccessSemantics.thisProperty();
         } else {
           return new DynamicAccess.dynamicProperty(node.receiver);
         }
-      } else if (element.impliesType) {
+      } else if (element != null && element.impliesType) {
         // TODO(johnniwinther): Provide an [ErroneousElement].
         // This happens for code like `C.this`.
         return new StaticAccess.unresolved(null);
       } else {
-        return handleStaticallyResolvedAccess(node, element, getter);
+        return handleStaticallyResolvedAccess(
+            node, element, getter, isCompound: isCompound);
       }
     }
   }
 
   ConstructorAccessSemantics computeConstructorAccessSemantics(
         ConstructorElement constructor,
-        DartType type) {
+        DartType type,
+        {bool mustBeConstant: false}) {
+    if (mustBeConstant && !constructor.isConst) {
+      return new ConstructorAccessSemantics(
+          ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, constructor, type);
+    }
     if (constructor.isErroneous) {
       if (constructor is ErroneousElement) {
         ErroneousElement error = constructor;
@@ -444,7 +574,8 @@
     } else if (constructor.isRedirectingFactory) {
       ConstructorElement effectiveTarget = constructor.effectiveTarget;
       if (effectiveTarget == constructor ||
-          effectiveTarget.isErroneous) {
+          effectiveTarget.isErroneous ||
+          (mustBeConstant && !effectiveTarget.isConst)) {
         return new ConstructorAccessSemantics(
             ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY,
             constructor,
@@ -486,26 +617,24 @@
   }
 
   NewStructure computeNewStructure(NewExpression node) {
-    if (node.isConst) {
-      ConstantExpression constant = elements.getConstant(node);
-      if (constant is ConstructedConstantExpression) {
-        return new ConstInvokeStructure(constant);
-      }
-    }
-
     Element element = elements[node.send];
     Selector selector = elements.getSelector(node.send);
     DartType type = elements.getType(node);
 
-    ConstructorAccessSemantics constructorAccessSemantics;
+    ConstructorAccessSemantics constructorAccessSemantics =
+        computeConstructorAccessSemantics(
+            element, type, mustBeConstant: node.isConst);
     if (node.isConst) {
-      // This is a non-constant constant constructor invocation, like
-      // `const Const(method())`.
-      constructorAccessSemantics = new ConstructorAccessSemantics(
-          ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type);
-    } else {
-      constructorAccessSemantics =
-          computeConstructorAccessSemantics(element, type);
+      ConstantExpression constant = elements.getConstant(node);
+      if (constructorAccessSemantics.isErroneous ||
+          constant is! ConstructedConstantExpression) {
+        // This is a non-constant constant constructor invocation, like
+        // `const Const(method())`.
+        constructorAccessSemantics = new ConstructorAccessSemantics(
+            ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type);
+      } else {
+        return new ConstInvokeStructure(constant);
+      }
     }
     return new NewInvokeStructure(constructorAccessSemantics, selector);
   }
diff --git a/pkg/compiler/lib/src/resolution/send_structure.dart b/pkg/compiler/lib/src/resolution/send_structure.dart
index c1a80aa..bae22a9 100644
--- a/pkg/compiler/lib/src/resolution/send_structure.dart
+++ b/pkg/compiler/lib/src/resolution/send_structure.dart
@@ -59,6 +59,21 @@
   String toString() => 'invalid assert';
 }
 
+/// 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);
+  }
+
+  String toString() => '??';
+}
+
 /// The structure for a [Send] of the form `a && b`.
 class LogicalAndStructure<R, A> implements SendStructure<R, A> {
   const LogicalAndStructure();
@@ -161,6 +176,14 @@
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
       case AccessKind.DYNAMIC_PROPERTY:
+        if (node.isConditional) {
+          return visitor.visitIfNotNullDynamicPropertyInvoke(
+              node,
+              node.receiver,
+              node.argumentsNode,
+              selector,
+              arg);
+        }
         return visitor.visitDynamicPropertyInvoke(
             node,
             node.receiver,
@@ -177,6 +200,7 @@
             callStructure,
             arg);
       case AccessKind.LOCAL_VARIABLE:
+      case AccessKind.FINAL_LOCAL_VARIABLE:
         return visitor.visitLocalVariableInvoke(
             node,
             semantics.element,
@@ -186,6 +210,7 @@
             callStructure,
             arg);
       case AccessKind.PARAMETER:
+      case AccessKind.FINAL_PARAMETER:
         return visitor.visitParameterInvoke(
             node,
             semantics.element,
@@ -195,6 +220,7 @@
             callStructure,
             arg);
       case AccessKind.STATIC_FIELD:
+      case AccessKind.FINAL_STATIC_FIELD:
         return visitor.visitStaticFieldInvoke(
             node,
             semantics.element,
@@ -216,13 +242,14 @@
             callStructure,
             arg);
       case AccessKind.STATIC_SETTER:
-        return visitor.errorStaticSetterInvoke(
+        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,
@@ -244,7 +271,7 @@
             callStructure,
             arg);
       case AccessKind.TOPLEVEL_SETTER:
-        return visitor.errorTopLevelSetterInvoke(
+        return visitor.visitTopLevelSetterInvoke(
             node,
             semantics.element,
             node.argumentsNode,
@@ -298,6 +325,7 @@
             selector,
             arg);
       case AccessKind.SUPER_FIELD:
+      case AccessKind.SUPER_FINAL_FIELD:
         return visitor.visitSuperFieldInvoke(
             node,
             semantics.element,
@@ -319,7 +347,7 @@
             callStructure,
             arg);
       case AccessKind.SUPER_SETTER:
-        return visitor.errorSuperSetterInvoke(
+        return visitor.visitSuperSetterInvoke(
             node,
             semantics.element,
             node.argumentsNode,
@@ -419,6 +447,13 @@
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
       case AccessKind.DYNAMIC_PROPERTY:
+        if (node.isConditional) {
+          return visitor.visitIfNotNullDynamicPropertyGet(
+              node,
+              node.receiver,
+              selector,
+              arg);
+        }
         return visitor.visitDynamicPropertyGet(
             node,
             node.receiver,
@@ -430,16 +465,19 @@
             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,
@@ -455,11 +493,12 @@
             semantics.element,
             arg);
       case AccessKind.STATIC_SETTER:
-        return visitor.errorStaticSetterGet(
+        return visitor.visitStaticSetterGet(
             node,
             semantics.element,
             arg);
       case AccessKind.TOPLEVEL_FIELD:
+      case AccessKind.FINAL_TOPLEVEL_FIELD:
         return visitor.visitTopLevelFieldGet(
             node,
             semantics.element,
@@ -475,7 +514,7 @@
             semantics.element,
             arg);
       case AccessKind.TOPLEVEL_SETTER:
-        return visitor.errorTopLevelSetterGet(
+        return visitor.visitTopLevelSetterGet(
             node,
             semantics.element,
             arg);
@@ -511,6 +550,7 @@
             selector,
             arg);
       case AccessKind.SUPER_FIELD:
+      case AccessKind.SUPER_FINAL_FIELD:
         return visitor.visitSuperFieldGet(
             node,
             semantics.element,
@@ -526,7 +566,7 @@
             semantics.element,
             arg);
       case AccessKind.SUPER_SETTER:
-        return visitor.errorSuperSetterGet(
+        return visitor.visitSuperSetterGet(
             node,
             semantics.element,
             arg);
@@ -568,14 +608,22 @@
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
       case AccessKind.DYNAMIC_PROPERTY:
-          return visitor.visitDynamicPropertySet(
+        if (node.isConditional) {
+          return visitor.visitIfNotNullDynamicPropertySet(
             node,
             node.receiver,
             selector,
             node.arguments.single,
             arg);
+        }
+        return visitor.visitDynamicPropertySet(
+          node,
+          node.receiver,
+          selector,
+          node.arguments.single,
+          arg);
       case AccessKind.LOCAL_FUNCTION:
-        return visitor.errorLocalFunctionSet(
+        return visitor.visitLocalFunctionSet(
             node,
             semantics.element,
             node.arguments.single,
@@ -586,26 +634,44 @@
             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.errorStaticFunctionSet(
+        return visitor.visitStaticFunctionSet(
             node,
             semantics.element,
             node.arguments.single,
             arg);
       case AccessKind.STATIC_GETTER:
-        return visitor.errorStaticGetterSet(
+        return visitor.visitStaticGetterSet(
             node,
             semantics.element,
             node.arguments.single,
@@ -622,14 +688,20 @@
             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.errorTopLevelFunctionSet(
+        return visitor.visitTopLevelFunctionSet(
             node,
             semantics.element,
             node.arguments.single,
             arg);
       case AccessKind.TOPLEVEL_GETTER:
-        return visitor.errorTopLevelGetterSet(
+        return visitor.visitTopLevelGetterSet(
             node,
             semantics.element,
             node.arguments.single,
@@ -641,25 +713,25 @@
             node.arguments.single,
             arg);
       case AccessKind.CLASS_TYPE_LITERAL:
-        return visitor.errorClassTypeLiteralSet(
+        return visitor.visitClassTypeLiteralSet(
             node,
             semantics.constant,
             node.arguments.single,
             arg);
       case AccessKind.TYPEDEF_TYPE_LITERAL:
-        return visitor.errorTypedefTypeLiteralSet(
+        return visitor.visitTypedefTypeLiteralSet(
             node,
             semantics.constant,
             node.arguments.single,
             arg);
       case AccessKind.DYNAMIC_TYPE_LITERAL:
-        return visitor.errorDynamicTypeLiteralSet(
+        return visitor.visitDynamicTypeLiteralSet(
             node,
             semantics.constant,
             node.arguments.single,
             arg);
       case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-        return visitor.errorTypeVariableTypeLiteralSet(
+        return visitor.visitTypeVariableTypeLiteralSet(
             node,
             semantics.element,
             node.arguments.single,
@@ -682,14 +754,20 @@
             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.errorSuperMethodSet(
+        return visitor.visitSuperMethodSet(
             node,
             semantics.element,
             node.arguments.single,
             arg);
       case AccessKind.SUPER_GETTER:
-        return visitor.errorSuperGetterSet(
+        return visitor.visitSuperGetterSet(
             node,
             semantics.element,
             node.arguments.single,
@@ -706,7 +784,7 @@
       case AccessKind.UNRESOLVED_SUPER:
         // TODO(johnniwinther): Handle this separately.
       case AccessKind.UNRESOLVED:
-        return visitor.errorUnresolvedSet(
+        return visitor.visitUnresolvedSet(
             node,
             semantics.element,
             node.arguments.single,
@@ -726,10 +804,7 @@
   /// The target of the negation.
   final AccessSemantics semantics;
 
-  // TODO(johnniwinther): Should we store this?
-  final Selector selector;
-
-  NotStructure(this.semantics, this.selector);
+  NotStructure(this.semantics);
 
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
@@ -745,7 +820,7 @@
     throw new SpannableAssertionFailure(node, "Invalid setter: ${semantics}");
   }
 
-  String toString() => 'not($selector,$semantics)';
+  String toString() => 'not($semantics)';
 }
 
 /// The structure for a [Send] that is an invocation of a user definable unary
@@ -757,11 +832,7 @@
   /// The user definable unary operator.
   final UnaryOperator operator;
 
-  // TODO(johnniwinther): Should we store this?
-  /// The [Selector] for the unary operator invocation.
-  final Selector selector;
-
-  UnaryStructure(this.semantics, this.operator, this.selector);
+  UnaryStructure(this.semantics, this.operator);
 
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
@@ -816,11 +887,7 @@
   /// The target of the left operand.
   final AccessSemantics semantics;
 
-  // TODO(johnniwinther): Should we store this?
-  /// The [Selector] for the `[]` invocation.
-  final Selector selector;
-
-  IndexStructure(this.semantics, this.selector);
+  IndexStructure(this.semantics);
 
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
@@ -856,11 +923,7 @@
   /// The target of the left operand.
   final AccessSemantics semantics;
 
-  // TODO(johnniwinther): Should we store this?
-  /// The [Selector] for the `==` invocation.
-  final Selector selector;
-
-  EqualsStructure(this.semantics, this.selector);
+  EqualsStructure(this.semantics);
 
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
@@ -892,11 +955,7 @@
   /// The target of the left operand.
   final AccessSemantics semantics;
 
-  // TODO(johnniwinther): Should we store this?
-  /// The [Selector] for the underlying `==` invocation.
-  final Selector selector;
-
-  NotEqualsStructure(this.semantics, this.selector);
+  NotEqualsStructure(this.semantics);
 
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
@@ -932,11 +991,7 @@
   /// The user definable binary operator.
   final BinaryOperator operator;
 
-  // TODO(johnniwinther): Should we store this?
-  /// The [Selector] for the binary operator invocation.
-  final Selector selector;
-
-  BinaryStructure(this.semantics, this.operator, this.selector);
+  BinaryStructure(this.semantics, this.operator);
 
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
@@ -1067,6 +1122,13 @@
             node.arguments.single,
             operator,
             arg);
+      case AccessKind.UNRESOLVED_SUPER:
+        return visitor.visitUnresolvedSuperIndexPrefix(
+            node,
+            semantics.element,
+            node.arguments.single,
+            operator,
+            arg);
       case AccessKind.COMPOUND:
         CompoundAccessSemantics compoundSemantics = semantics;
         switch (compoundSemantics.compoundAccessKind) {
@@ -1082,6 +1144,7 @@
             return visitor.visitUnresolvedSuperGetterIndexPrefix(
                 node,
                 compoundSemantics.getter,
+                compoundSemantics.setter,
                 node.arguments.single,
                 operator,
                 arg);
@@ -1138,6 +1201,13 @@
             node.arguments.single,
             operator,
             arg);
+      case AccessKind.UNRESOLVED_SUPER:
+        return visitor.visitUnresolvedSuperIndexPostfix(
+            node,
+            semantics.element,
+            node.arguments.single,
+            operator,
+            arg);
       case AccessKind.COMPOUND:
         CompoundAccessSemantics compoundSemantics = semantics;
         switch (compoundSemantics.compoundAccessKind) {
@@ -1153,6 +1223,7 @@
             return visitor.visitUnresolvedSuperGetterIndexPostfix(
                 node,
                 compoundSemantics.getter,
+                compoundSemantics.setter,
                 node.arguments.single,
                 operator,
                 arg);
@@ -1201,6 +1272,16 @@
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
       case AccessKind.DYNAMIC_PROPERTY:
+        if (node.isConditional) {
+          return visitor.visitIfNotNullDynamicPropertyCompound(
+              node,
+              node.receiver,
+              operator,
+              node.arguments.single,
+              getterSelector,
+              setterSelector,
+              arg);
+        }
         return visitor.visitDynamicPropertyCompound(
             node,
             node.receiver,
@@ -1210,7 +1291,7 @@
             setterSelector,
             arg);
       case AccessKind.LOCAL_FUNCTION:
-        return visitor.errorLocalFunctionCompound(
+        return visitor.visitLocalFunctionCompound(
             node,
             semantics.element,
             operator,
@@ -1223,6 +1304,13 @@
             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,
@@ -1230,6 +1318,13 @@
             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,
@@ -1237,9 +1332,20 @@
             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:
-        // TODO(johnniwinther): Handle this.
-        break;
+        return visitor.visitStaticMethodCompound(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
       case AccessKind.STATIC_GETTER:
         // This is not a valid case.
         break;
@@ -1253,9 +1359,20 @@
             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:
-        // TODO(johnniwinther): Handle this.
-        break;
+        return visitor.visitTopLevelMethodCompound(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
       case AccessKind.TOPLEVEL_GETTER:
         // This is not a valid case.
         break;
@@ -1263,28 +1380,28 @@
         // This is not a valid case.
         break;
       case AccessKind.CLASS_TYPE_LITERAL:
-        return visitor.errorClassTypeLiteralCompound(
+        return visitor.visitClassTypeLiteralCompound(
             node,
             semantics.constant,
             operator,
             node.arguments.single,
             arg);
       case AccessKind.TYPEDEF_TYPE_LITERAL:
-        return visitor.errorTypedefTypeLiteralCompound(
+        return visitor.visitTypedefTypeLiteralCompound(
             node,
             semantics.constant,
             operator,
             node.arguments.single,
             arg);
       case AccessKind.DYNAMIC_TYPE_LITERAL:
-        return visitor.errorDynamicTypeLiteralCompound(
+        return visitor.visitDynamicTypeLiteralCompound(
             node,
             semantics.constant,
             operator,
             node.arguments.single,
             arg);
       case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-        return visitor.errorTypeVariableTypeLiteralCompound(
+        return visitor.visitTypeVariableTypeLiteralCompound(
             node,
             semantics.element,
             operator,
@@ -1311,9 +1428,20 @@
             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:
-        // TODO(johnniwinther): Handle this.
-        break;
+        return visitor.visitSuperMethodCompound(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
       case AccessKind.SUPER_GETTER:
         // This is not a valid case.
         break;
@@ -1324,9 +1452,14 @@
         // 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:
-        // TODO(johnniwinther): Support these through [AccessKind.COMPOUND].
-        return visitor.errorUnresolvedCompound(
+        return visitor.visitUnresolvedCompound(
             node,
             semantics.element,
             operator,
@@ -1351,6 +1484,22 @@
                 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,
@@ -1367,6 +1516,22 @@
                 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:
             // TODO(johnniwinther): Handle this.
             break;
@@ -1403,11 +1568,18 @@
                 node.arguments.single,
                 arg);
           case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-            // TODO(johnniwinther): Handle these separately.
-            return visitor.errorUnresolvedCompound(
+            return visitor.visitUnresolvedSuperGetterCompound(
                 node,
-                semantics.element,
+                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);
@@ -1450,6 +1622,14 @@
             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.COMPOUND:
         CompoundAccessSemantics compoundSemantics = semantics;
         switch (compoundSemantics.compoundAccessKind) {
@@ -1466,6 +1646,7 @@
             return visitor.visitUnresolvedSuperGetterCompoundIndexSet(
                 node,
                 compoundSemantics.getter,
+                compoundSemantics.setter,
                 node.arguments.first,
                 operator,
                 node.arguments.tail.head,
@@ -1518,6 +1699,15 @@
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
       case AccessKind.DYNAMIC_PROPERTY:
+        if (node.isConditional) {
+          return visitor.visitIfNotNullDynamicPropertyPrefix(
+              node,
+              node.receiver,
+              operator,
+              getterSelector,
+              setterSelector,
+              arg);
+        }
         return visitor.visitDynamicPropertyPrefix(
             node,
             node.receiver,
@@ -1526,7 +1716,7 @@
             setterSelector,
             arg);
       case AccessKind.LOCAL_FUNCTION:
-        return visitor.errorLocalFunctionPrefix(
+        return visitor.visitLocalFunctionPrefix(
             node,
             semantics.element,
             operator,
@@ -1537,21 +1727,42 @@
             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:
-        // TODO(johnniwinther): Handle this.
-        break;
+        return visitor.visitStaticMethodPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.STATIC_GETTER:
         // This is not a valid case.
         break;
@@ -1564,9 +1775,18 @@
             semantics.element,
             operator,
             arg);
+      case AccessKind.FINAL_TOPLEVEL_FIELD:
+        return visitor.visitFinalTopLevelFieldPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.TOPLEVEL_METHOD:
-        // TODO(johnniwinther): Handle this.
-        break;
+        return visitor.visitTopLevelMethodPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.TOPLEVEL_GETTER:
         // This is not a valid case.
         break;
@@ -1574,25 +1794,25 @@
         // This is not a valid case.
         break;
       case AccessKind.CLASS_TYPE_LITERAL:
-        return visitor.errorClassTypeLiteralPrefix(
+        return visitor.visitClassTypeLiteralPrefix(
             node,
             semantics.constant,
             operator,
             arg);
       case AccessKind.TYPEDEF_TYPE_LITERAL:
-        return visitor.errorTypedefTypeLiteralPrefix(
+        return visitor.visitTypedefTypeLiteralPrefix(
             node,
             semantics.constant,
             operator,
             arg);
       case AccessKind.DYNAMIC_TYPE_LITERAL:
-        return visitor.errorDynamicTypeLiteralPrefix(
+        return visitor.visitDynamicTypeLiteralPrefix(
             node,
             semantics.constant,
             operator,
             arg);
       case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-        return visitor.errorTypeVariableTypeLiteralPrefix(
+        return visitor.visitTypeVariableTypeLiteralPrefix(
             node,
             semantics.element,
             operator,
@@ -1616,9 +1836,18 @@
             semantics.element,
             operator,
             arg);
+      case AccessKind.SUPER_FINAL_FIELD:
+        return visitor.visitFinalSuperFieldPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.SUPER_METHOD:
-        // TODO(johnniwinther): Handle this.
-        break;
+        return visitor.visitSuperMethodPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.SUPER_GETTER:
         // This is not a valid case.
         break;
@@ -1629,9 +1858,13 @@
         // TODO(johnniwinther): Should this be a valid case?
         break;
       case AccessKind.UNRESOLVED_SUPER:
+        return visitor.visitUnresolvedSuperPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.UNRESOLVED:
-        // TODO(johnniwinther): Support these through [AccessKind.COMPOUND].
-        return visitor.errorUnresolvedPrefix(
+        return visitor.visitUnresolvedPrefix(
             node,
             semantics.element,
             operator,
@@ -1653,6 +1886,27 @@
                 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,
@@ -1667,6 +1921,20 @@
                 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,
@@ -1703,11 +1971,17 @@
                 operator,
                 arg);
           case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-            // TODO(johnniwinther): Handle these directly.
-            return visitor.errorUnresolvedPrefix(
+            return visitor.visitUnresolvedSuperGetterPrefix(
                 node,
-                semantics.element,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
+            return visitor.visitUnresolvedSuperSetterPrefix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
                 operator,
                 arg);
         }
@@ -1742,6 +2016,15 @@
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
       case AccessKind.DYNAMIC_PROPERTY:
+        if (node.isConditional) {
+          return visitor.visitIfNotNullDynamicPropertyPostfix(
+              node,
+              node.receiver,
+              operator,
+              getterSelector,
+              setterSelector,
+              arg);
+        }
         return visitor.visitDynamicPropertyPostfix(
             node,
             node.receiver,
@@ -1750,7 +2033,7 @@
             setterSelector,
             arg);
       case AccessKind.LOCAL_FUNCTION:
-        return visitor.errorLocalFunctionPostfix(
+        return visitor.visitLocalFunctionPostfix(
             node,
             semantics.element,
             operator,
@@ -1761,21 +2044,42 @@
             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:
-        // TODO(johnniwinther): Handle this.
-        break;
+        return visitor.visitStaticMethodPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.STATIC_GETTER:
         // This is not a valid case.
         break;
@@ -1788,9 +2092,18 @@
             semantics.element,
             operator,
             arg);
+      case AccessKind.FINAL_TOPLEVEL_FIELD:
+        return visitor.visitFinalTopLevelFieldPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.TOPLEVEL_METHOD:
-        // TODO(johnniwinther): Handle this.
-        break;
+        return visitor.visitTopLevelMethodPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.TOPLEVEL_GETTER:
         // This is not a valid case.
         break;
@@ -1798,25 +2111,25 @@
         // This is not a valid case.
         break;
       case AccessKind.CLASS_TYPE_LITERAL:
-        return visitor.errorClassTypeLiteralPostfix(
+        return visitor.visitClassTypeLiteralPostfix(
             node,
             semantics.constant,
             operator,
             arg);
       case AccessKind.TYPEDEF_TYPE_LITERAL:
-        return visitor.errorTypedefTypeLiteralPostfix(
+        return visitor.visitTypedefTypeLiteralPostfix(
             node,
             semantics.constant,
             operator,
             arg);
       case AccessKind.DYNAMIC_TYPE_LITERAL:
-        return visitor.errorDynamicTypeLiteralPostfix(
+        return visitor.visitDynamicTypeLiteralPostfix(
             node,
             semantics.constant,
             operator,
             arg);
       case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
-        return visitor.errorTypeVariableTypeLiteralPostfix(
+        return visitor.visitTypeVariableTypeLiteralPostfix(
             node,
             semantics.element,
             operator,
@@ -1840,9 +2153,18 @@
             semantics.element,
             operator,
             arg);
+      case AccessKind.SUPER_FINAL_FIELD:
+        return visitor.visitFinalSuperFieldPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.SUPER_METHOD:
-        // TODO(johnniwinther): Handle this.
-        break;
+        return visitor.visitSuperMethodPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.SUPER_GETTER:
         // This is not a valid case.
         break;
@@ -1853,9 +2175,13 @@
         // TODO(johnniwinther): Should this be a valid case?
         break;
       case AccessKind.UNRESOLVED_SUPER:
+        return visitor.visitUnresolvedSuperPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
       case AccessKind.UNRESOLVED:
-        // TODO(johnniwinther): Support these through [AccessKind.COMPOUND].
-        return visitor.errorUnresolvedPostfix(
+        return visitor.visitUnresolvedPostfix(
             node,
             semantics.element,
             operator,
@@ -1870,6 +2196,20 @@
                 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,
@@ -1891,6 +2231,20 @@
                 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,
@@ -1927,11 +2281,17 @@
                 operator,
                 arg);
           case CompoundAccessKind.UNRESOLVED_SUPER_GETTER:
-          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
-            // TODO(johnniwinther): Handle these directly.
-            return visitor.errorUnresolvedPostfix(
+            return visitor.visitUnresolvedSuperGetterPostfix(
                 node,
-                semantics.element,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.UNRESOLVED_SUPER_SETTER:
+            return visitor.visitUnresolvedSuperSetterPostfix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
                 operator,
                 arg);
         }
diff --git a/pkg/compiler/lib/src/resolution/signatures.dart b/pkg/compiler/lib/src/resolution/signatures.dart
index 948a0cb..02c86a7 100644
--- a/pkg/compiler/lib/src/resolution/signatures.dart
+++ b/pkg/compiler/lib/src/resolution/signatures.dart
@@ -13,7 +13,7 @@
   final Scope scope;
   final MessageKind defaultValuesError;
   final bool createRealParameters;
-  Link<Element> optionalParameters = const Link<Element>();
+  List<Element> optionalParameters = const <Element>[];
   int optionalParameterCount = 0;
   bool isOptionalParameter = false;
   bool optionalParametersAreNamed = false;
@@ -42,7 +42,7 @@
     isOptionalParameter = true;
     LinkBuilder<Element> elements = analyzeNodes(node.nodes);
     optionalParameterCount = elements.length;
-    optionalParameters = elements.toLink();
+    optionalParameters = elements.toList();
   }
 
   FormalElementX visitVariableDefinitions(VariableDefinitions node) {
@@ -274,7 +274,7 @@
     SignatureResolver visitor = new SignatureResolver(compiler, element,
         registry, defaultValuesError: defaultValuesError,
         createRealParameters: createRealParameters);
-    Link<Element> parameters = const Link<Element>();
+    List<Element> parameters = const <Element>[];
     int requiredParameterCount = 0;
     if (formalParameters == null) {
       if (!element.isGetter) {
@@ -300,7 +300,7 @@
       LinkBuilder<Element> parametersBuilder =
         visitor.analyzeNodes(formalParameters.nodes);
       requiredParameterCount  = parametersBuilder.length;
-      parameters = parametersBuilder.toLink();
+      parameters = parametersBuilder.toList();
     }
     DartType returnType;
     if (element.isFactoryConstructor) {
diff --git a/pkg/compiler/lib/src/resolution/tree_elements.dart b/pkg/compiler/lib/src/resolution/tree_elements.dart
new file mode 100644
index 0000000..a9e9366
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/tree_elements.dart
@@ -0,0 +1,467 @@
+// 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 resolution;
+
+abstract class TreeElements {
+  AnalyzableElement get analyzedElement;
+  Iterable<Node> get superUses;
+
+  /// Iterables of the dependencies that this [TreeElement] records of
+  /// [analyzedElement].
+  Iterable<Element> get allElements;
+  void forEachConstantNode(f(Node n, ConstantExpression c));
+
+  /// A set of additional dependencies.  See [registerDependency] below.
+  Iterable<Element> get otherDependencies;
+
+  Element operator[](Node node);
+
+  SendStructure getSendStructure(Send send);
+
+  // TODO(johnniwinther): Investigate whether [Node] could be a [Send].
+  Selector getSelector(Node node);
+  Selector getGetterSelectorInComplexSendSet(SendSet node);
+  Selector getOperatorSelectorInComplexSendSet(SendSet node);
+  DartType getType(Node node);
+  void setSelector(Node node, Selector selector);
+  void setGetterSelectorInComplexSendSet(SendSet node, Selector selector);
+  void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector);
+
+  /// Returns the for-in loop variable for [node].
+  Element getForInVariable(ForIn node);
+  Selector getIteratorSelector(ForIn node);
+  Selector getMoveNextSelector(ForIn node);
+  Selector getCurrentSelector(ForIn node);
+  void setIteratorSelector(ForIn node, Selector selector);
+  void setMoveNextSelector(ForIn node, Selector selector);
+  void setCurrentSelector(ForIn node, Selector selector);
+  void setConstant(Node node, ConstantExpression constant);
+  ConstantExpression getConstant(Node node);
+  bool isAssert(Send send);
+
+  /// 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.
+  DartType getTypeLiteralType(Send node);
+
+  /// Register additional dependencies required by [analyzedElement].
+  /// For example, elements that are used by a backend.
+  void registerDependency(Element element);
+
+  /// 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);
+}
+
+class TreeElementMapping implements TreeElements {
+  final AnalyzableElement analyzedElement;
+  Map<Spannable, Selector> _selectors;
+  Map<Node, DartType> _types;
+  Setlet<Node> _superUses;
+  Setlet<Element> _otherDependencies;
+  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;
+  Setlet<Element> _elements;
+  Setlet<Send> _asserts;
+  Maplet<Send, SendStructure> _sendStructureMap;
+
+  /// 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;
+
+  final int hashCode = ++_hashCodeCounter;
+  static int _hashCodeCounter = 0;
+
+  TreeElementMapping(this.analyzedElement);
+
+  operator []=(Node node, Element element) {
+    // TODO(johnniwinther): Simplify this invariant to use only declarations in
+    // [TreeElements].
+    assert(invariant(node, () {
+      if (!element.isErroneous && analyzedElement != null && element.isPatch) {
+        return analyzedElement.implementationLibrary.isPatch;
+      }
+      return true;
+    }));
+    // TODO(ahe): Investigate why the invariant below doesn't hold.
+    // assert(invariant(node,
+    //                  getTreeElement(node) == element ||
+    //                  getTreeElement(node) == null,
+    //                  message: '${getTreeElement(node)}; $element'));
+
+    if (_elements == null) {
+      _elements = new Setlet<Element>();
+    }
+    _elements.add(element);
+    setTreeElement(node, element);
+  }
+
+  operator [](Node node) => getTreeElement(node);
+
+  SendStructure getSendStructure(Send send) {
+    if (_sendStructureMap == null) return null;
+    return _sendStructureMap[send];
+  }
+
+  void setSendStructure(Send send, SendStructure sendStructure) {
+    if (_sendStructureMap == null) {
+      _sendStructureMap = new Maplet<Send, SendStructure>();
+    }
+    _sendStructureMap[send] = sendStructure;
+  }
+
+  void setType(Node node, DartType type) {
+    if (_types == null) {
+      _types = new Maplet<Node, DartType>();
+    }
+    _types[node] = type;
+  }
+
+  DartType getType(Node node) => _types != null ? _types[node] : null;
+
+  Iterable<Node> get superUses {
+    return _superUses != null ? _superUses : const <Node>[];
+  }
+
+  void addSuperUse(Node node) {
+    if (_superUses == null) {
+      _superUses = new Setlet<Node>();
+    }
+    _superUses.add(node);
+  }
+
+  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);
+  }
+
+  Selector getSelector(Node node) => _getSelector(node);
+
+  int getSelectorCount() => _selectors == null ? 0 : _selectors.length;
+
+  void setGetterSelectorInComplexSendSet(SendSet node, Selector selector) {
+    _setSelector(node.selector, selector);
+  }
+
+  Selector getGetterSelectorInComplexSendSet(SendSet node) {
+    return _getSelector(node.selector);
+  }
+
+  void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector) {
+    _setSelector(node.assignmentOperator, selector);
+  }
+
+  Selector getOperatorSelectorInComplexSendSet(SendSet node) {
+    return _getSelector(node.assignmentOperator);
+  }
+
+  // The following methods set selectors on the "for in" node. Since
+  // we're using three selectors, we need to use children of the node,
+  // and we arbitrarily choose which ones.
+
+  void setIteratorSelector(ForIn node, Selector selector) {
+    _setSelector(node, selector);
+  }
+
+  Selector getIteratorSelector(ForIn node) {
+    return _getSelector(node);
+  }
+
+  void setMoveNextSelector(ForIn node, Selector selector) {
+    _setSelector(node.forToken, selector);
+  }
+
+  Selector getMoveNextSelector(ForIn node) {
+    return _getSelector(node.forToken);
+  }
+
+  void setCurrentSelector(ForIn node, Selector selector) {
+    _setSelector(node.inToken, selector);
+  }
+
+  Selector getCurrentSelector(ForIn node) {
+    return _getSelector(node.inToken);
+  }
+
+  Element getForInVariable(ForIn node) {
+    return this[node];
+  }
+
+  void setConstant(Node node, ConstantExpression constant) {
+    if (_constants == null) {
+      _constants = new Maplet<Node, ConstantExpression>();
+    }
+    _constants[node] = constant;
+  }
+
+  ConstantExpression getConstant(Node node) {
+    return _constants != null ? _constants[node] : null;
+  }
+
+  bool isTypeLiteral(Send node) {
+    return getType(node) != null;
+  }
+
+  DartType getTypeLiteralType(Send node) {
+    return getType(node);
+  }
+
+  void registerDependency(Element element) {
+    if (element == null) return;
+    if (_otherDependencies == null) {
+      _otherDependencies = new Setlet<Element>();
+    }
+    _otherDependencies.add(element.implementation);
+  }
+
+  Iterable<Element> get otherDependencies {
+    return _otherDependencies != null ? _otherDependencies : const <Element>[];
+  }
+
+  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);
+  }
+
+  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);
+  }
+
+  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);
+  }
+
+  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)';
+
+  Iterable<Element> get allElements {
+    return _elements != null ? _elements : const <Element>[];
+  }
+
+  void forEachConstantNode(f(Node n, ConstantExpression c)) {
+    if (_constants != null) {
+      _constants.forEach(f);
+    }
+  }
+
+  void setAssert(Send node) {
+    if (_asserts == null) {
+      _asserts = new Setlet<Send>();
+    }
+    _asserts.add(node);
+  }
+
+  bool isAssert(Send node) {
+    return _asserts != null && _asserts.contains(node);
+  }
+
+  FunctionElement getFunctionDefinition(FunctionExpression node) {
+    return this[node];
+  }
+
+  ConstructorElement getRedirectingTargetConstructor(
+      RedirectingFactoryBody node) {
+    return this[node];
+  }
+
+  void defineTarget(Node node, JumpTarget target) {
+    if (_definedTargets == null) {
+      _definedTargets = new Maplet<Node, JumpTarget>();
+    }
+    _definedTargets[node] = target;
+  }
+
+  void undefineTarget(Node node) {
+    if (_definedTargets != null) {
+      _definedTargets.remove(node);
+      if (_definedTargets.isEmpty) {
+        _definedTargets = null;
+      }
+    }
+  }
+
+  JumpTarget getTargetDefinition(Node node) {
+    return _definedTargets != null ? _definedTargets[node] : null;
+  }
+
+  void registerTargetOf(GotoStatement node, JumpTarget target) {
+    if (_usedTargets == null) {
+      _usedTargets = new Maplet<GotoStatement, JumpTarget>();
+    }
+    _usedTargets[node] = target;
+  }
+
+  JumpTarget getTargetOf(GotoStatement node) {
+    return _usedTargets != null ? _usedTargets[node] : null;
+  }
+
+  void defineLabel(Label label, LabelDefinition target) {
+    if (_definedLabels == null) {
+      _definedLabels = new Maplet<Label, LabelDefinition>();
+    }
+    _definedLabels[label] = target;
+  }
+
+  void undefineLabel(Label label) {
+    if (_definedLabels != null) {
+      _definedLabels.remove(label);
+      if (_definedLabels.isEmpty) {
+        _definedLabels = null;
+      }
+    }
+  }
+
+  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;
+  }
+
+  LabelDefinition getTargetLabel(GotoStatement node) {
+    assert(node.target != null);
+    return _targetLabels != null ? _targetLabels[node] : null;
+  }
+}
+
+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(invariant(this, _treeElements !=null,
+        message: "TreeElements have not been computed for $this."));
+    return _treeElements;
+  }
+
+  void reuseElement() {
+    _treeElements = null;
+  }
+}
diff --git a/pkg/compiler/lib/src/resolution/type_resolver.dart b/pkg/compiler/lib/src/resolution/type_resolver.dart
new file mode 100644
index 0000000..85c2171
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/type_resolver.dart
@@ -0,0 +1,263 @@
+// 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 resolution;
+
+class TypeResolver {
+  final Compiler compiler;
+
+  TypeResolver(this.compiler);
+
+  /// Tries to resolve the type name as an element.
+  Element resolveTypeName(Identifier prefixName,
+                          Identifier typeName,
+                          Scope scope,
+                          {bool deferredIsMalformed: true}) {
+    Element element;
+    bool deferredTypeAnnotation = false;
+    if (prefixName != null) {
+      Element prefixElement =
+          lookupInScope(compiler, 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);
+        // TODO(17260, sigurdm): The test for DartBackend is there because
+        // dart2dart outputs malformed types with prefix.
+        if (element != null &&
+            prefix.isDeferred &&
+            deferredIsMalformed &&
+            compiler.backend is! DartBackend) {
+          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 {
+      String stringValue = typeName.source;
+      element = lookupInScope(compiler, typeName, scope, typeName.source);
+    }
+    return element;
+  }
+
+  DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node,
+                                 {bool malformedIsError: false,
+                                  bool deferredIsMalformed: true}) {
+    ResolutionRegistry registry = visitor.registry;
+
+    Identifier typeName;
+    DartType type;
+
+    DartType checkNoTypeArguments(DartType type) {
+      List<DartType> arguments = new List<DartType>();
+      bool hasTypeArgumentMismatch = resolveTypeArguments(
+          visitor, node, const <DartType>[], arguments);
+      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 VoidType();
+        checkNoTypeArguments(type);
+        registry.useType(node, type);
+        return type;
+      } else if (identical(typeName.source, 'dynamic')) {
+        type = const DynamicType();
+        checkNoTypeArguments(type);
+        registry.useType(node, type);
+        return type;
+      }
+    }
+
+    Element element = resolveTypeName(prefixName, typeName, visitor.scope,
+                                      deferredIsMalformed: deferredIsMalformed);
+
+    DartType reportFailureAndCreateType(MessageKind messageKind,
+                                        Map messageArguments,
+                                        {DartType userProvidedBadType,
+                                         Element erroneousElement}) {
+      if (malformedIsError) {
+        visitor.error(node, messageKind, messageArguments);
+      } else {
+        registry.registerThrowRuntimeError();
+        visitor.warning(node, messageKind, messageArguments);
+      }
+      if (erroneousElement == null) {
+        registry.registerThrowRuntimeError();
+        erroneousElement = new ErroneousElementX(
+            messageKind, messageArguments, typeName.source,
+            visitor.enclosingElement);
+      }
+      List<DartType> arguments = <DartType>[];
+      resolveTypeArguments(visitor, node, const <DartType>[], arguments);
+      return new MalformedType(erroneousElement,
+              userProvidedBadType, arguments);
+    }
+
+    // Try to construct the type from the element.
+    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);
+      ambiguous.diagnose(registry.mapping.analyzedElement, compiler);
+    } else if (element.isErroneous) {
+      if (element is ErroneousElement) {
+        type = reportFailureAndCreateType(
+            element.messageKind, element.messageArguments,
+            erroneousElement: element);
+      } else {
+        type = const DynamicType();
+      }
+    } else if (!element.impliesType) {
+      type = reportFailureAndCreateType(
+          MessageKind.NOT_A_TYPE, {'node': node.typeName});
+    } else {
+      bool addTypeVariableBoundsCheck = false;
+      if (element.isClass) {
+        ClassElement cls = element;
+        // TODO(johnniwinther): [_ensureClassWillBeResolved] should imply
+        // [computeType].
+        compiler.resolver._ensureClassWillBeResolved(cls);
+        element.computeType(compiler);
+        List<DartType> arguments = <DartType>[];
+        bool hasTypeArgumentMismatch = resolveTypeArguments(
+            visitor, node, cls.typeVariables, arguments);
+        if (hasTypeArgumentMismatch) {
+          type = new BadInterfaceType(cls.declaration,
+              new InterfaceType.forUserProvidedBadType(cls.declaration,
+                                                       arguments));
+        } else {
+          if (arguments.isEmpty) {
+            type = cls.rawType;
+          } else {
+            type = new InterfaceType(cls.declaration, arguments.toList(growable: false));
+            addTypeVariableBoundsCheck = true;
+          }
+        }
+      } else if (element.isTypedef) {
+        TypedefElement typdef = element;
+        // TODO(johnniwinther): [ensureResolved] should imply [computeType].
+        typdef.ensureResolved(compiler);
+        element.computeType(compiler);
+        List<DartType> arguments = <DartType>[];
+        bool hasTypeArgumentMismatch = resolveTypeArguments(
+            visitor, node, typdef.typeVariables, arguments);
+        if (hasTypeArgumentMismatch) {
+          type = new BadTypedefType(typdef,
+              new TypedefType.forUserProvidedBadType(typdef, arguments));
+        } else {
+          if (arguments.isEmpty) {
+            type = typdef.rawType;
+          } else {
+            type = new TypedefType(typdef, arguments.toList(growable: false));
+            addTypeVariableBoundsCheck = true;
+          }
+        }
+      } else if (element.isTypeVariable) {
+        Element outer =
+            visitor.enclosingElement.outermostEnclosingMemberOrTopLevel;
+        bool isInFactoryConstructor =
+            outer != null && outer.isFactoryConstructor;
+        if (!outer.isClass &&
+            !outer.isTypedef &&
+            !Elements.hasAccessToTypeVariables(visitor.enclosingElement)) {
+          registry.registerThrowRuntimeError();
+          type = reportFailureAndCreateType(
+              MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
+              {'typeVariableName': node},
+              userProvidedBadType: element.computeType(compiler));
+        } else {
+          type = element.computeType(compiler);
+        }
+        type = checkNoTypeArguments(type);
+      } else {
+        compiler.internalError(node,
+            "Unexpected element kind ${element.kind}.");
+      }
+      if (addTypeVariableBoundsCheck) {
+        registry.registerTypeVariableBoundCheck();
+        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(TypeAnnotation node, GenericType type) {
+    void checkTypeVariableBound(_, DartType typeArgument,
+                                   TypeVariableType typeVariable,
+                                   DartType bound) {
+      if (!compiler.types.isSubtype(typeArgument, bound)) {
+        compiler.reportWarning(node,
+            MessageKind.INVALID_TYPE_VARIABLE_BOUND,
+            {'typeVariable': typeVariable,
+             'bound': bound,
+             'typeArgument': typeArgument,
+             'thisType': type.element.thisType});
+      }
+    };
+
+    compiler.types.checkTypeVariableBounds(type, 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,
+                            TypeAnnotation node,
+                            List<DartType> typeVariables,
+                            List<DartType> arguments) {
+    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) {
+        visitor.warning(
+            typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
+        typeArgumentCountMismatch = true;
+      }
+      DartType argType = resolveTypeAnnotation(visitor, typeArguments.head);
+      // TODO(karlklose): rewrite to not modify [arguments].
+      arguments.add(argType);
+    }
+    if (index < expectedVariables) {
+      visitor.warning(node.typeArguments,
+                      MessageKind.MISSING_TYPE_ARGUMENT);
+      typeArgumentCountMismatch = true;
+    }
+    return typeArgumentCountMismatch;
+  }
+}
diff --git a/pkg/compiler/lib/src/resolution/typedefs.dart b/pkg/compiler/lib/src/resolution/typedefs.dart
new file mode 100644
index 0000000..0c3badd
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/typedefs.dart
@@ -0,0 +1,123 @@
+// 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 resolution;
+
+class TypedefResolverVisitor extends TypeDefinitionVisitor {
+  TypedefElementX get element => enclosingElement;
+
+  TypedefResolverVisitor(Compiler compiler,
+                         TypedefElement typedefElement,
+                         ResolutionRegistry registry)
+      : super(compiler, typedefElement, registry);
+
+  visitTypedef(Typedef node) {
+    TypedefType type = element.computeType(compiler);
+    scope = new TypeDeclarationScope(scope, element);
+    resolveTypeVariableBounds(node.typeParameters);
+
+    FunctionSignature signature = SignatureResolver.analyze(
+        compiler, node.formals, node.returnType, element, registry,
+        defaultValuesError: MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT);
+    element.functionSignature = signature;
+
+    scope = new MethodScope(scope, element);
+    signature.forEachParameter(addToScope);
+
+    element.alias = signature.type;
+
+    void checkCyclicReference() {
+      element.checkCyclicReference(compiler);
+    }
+    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 BaseDartTypeVisitor {
+  final Compiler compiler;
+  final TypedefElementX element;
+  bool hasCyclicReference = false;
+
+  Link<TypedefElement> seenTypedefs = const Link<TypedefElement>();
+
+  int seenTypedefsCount = 0;
+
+  Link<TypeVariableElement> seenTypeVariables =
+      const Link<TypeVariableElement>();
+
+  TypedefCyclicVisitor(Compiler this.compiler, TypedefElement this.element);
+
+  visitType(DartType type, _) {
+    // Do nothing.
+  }
+
+  visitTypedefType(TypedefType 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.
+          compiler.reportError(element,
+              MessageKind.CYCLIC_TYPEDEF,
+              {'typedefName': element.name});
+        } else if (seenTypedefsCount == 2) {
+          // Cyclicity through one other typedef.
+          compiler.reportError(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)) {
+              compiler.reportError(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.alias =
+            new MalformedType(erroneousElement, typedefElement.alias);
+        element.hasBeenCheckedForCycles = true;
+      }
+    } else {
+      seenTypedefs = seenTypedefs.prepend(typedefElement);
+      seenTypedefsCount++;
+      type.visitChildren(this, null);
+      typedefElement.alias.accept(this, null);
+      seenTypedefs = seenTypedefs.tail;
+      seenTypedefsCount--;
+    }
+  }
+
+  visitFunctionType(FunctionType type, _) {
+    type.visitChildren(this, null);
+  }
+
+  visitInterfaceType(InterfaceType type, _) {
+    type.visitChildren(this, null);
+  }
+
+  visitTypeVariableType(TypeVariableType 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
new file mode 100644
index 0000000..a738b4f
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/variables.dart
@@ -0,0 +1,65 @@
+// 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 resolution;
+
+class VariableDefinitionsVisitor extends CommonResolverVisitor<Identifier> {
+  VariableDefinitions definitions;
+  ResolverVisitor resolver;
+  VariableList variables;
+
+  VariableDefinitionsVisitor(Compiler compiler,
+                             this.definitions,
+                             this.resolver,
+                             this.variables)
+      : super(compiler) {
+  }
+
+  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) {
+      compiler.reportError(
+          identifier, MessageKind.REFERENCE_IN_INITIALIZATION,
+          {'variableName': name});
+    }
+    return identifier;
+  }
+
+  Identifier visitIdentifier(Identifier node) {
+    // The variable is initialized to null.
+    registry.registerInstantiatedClass(compiler.nullClass);
+    if (definitions.modifiers.isConst) {
+      compiler.reportError(node, MessageKind.CONST_WITHOUT_INITIALIZER);
+    }
+    if (definitions.modifiers.isFinal &&
+        !resolver.allowFinalWithoutInitializer) {
+      compiler.reportError(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) {
+        compiler.enqueuer.resolution.addDeferredAction(element, () {
+          element.constant =
+              compiler.resolver.constantCompiler.compileConstant(element);
+        });
+      }
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/resolved_visitor.dart b/pkg/compiler/lib/src/resolved_visitor.dart
index 9cd81ba..d75834b 100644
--- a/pkg/compiler/lib/src/resolved_visitor.dart
+++ b/pkg/compiler/lib/src/resolved_visitor.dart
@@ -116,7 +116,9 @@
     } else if (Elements.isClosureSend(node, element)) {
       return visitor.visitClosureSend(node);
     } else {
-      if (Elements.isUnresolved(element)) {
+      if (node.isConditional) {
+        return visitor.visitDynamicSend(node);
+      } else if (Elements.isUnresolved(element)) {
         if (element == null) {
           // Example: f() with 'f' unbound.
           // This can only happen inside an instance method.
@@ -394,7 +396,7 @@
   }
 
   @override
-  R errorLocalFunctionPostfix(
+  R visitLocalFunctionPostfix(
       Send node,
       LocalFunctionElement function,
       op.IncDecOperator operator,
@@ -403,7 +405,7 @@
   }
 
   @override
-  R errorLocalFunctionPrefix(
+  R visitLocalFunctionPrefix(
       Send node,
       LocalFunctionElement function,
       op.IncDecOperator operator,
@@ -412,7 +414,7 @@
   }
 
   @override
-  R errorStaticSetterGet(
+  R visitStaticSetterGet(
       Send node,
       FunctionElement setter,
       ResolvedKindVisitor<R> visitor) {
@@ -420,7 +422,7 @@
   }
 
   @override
-  R errorStaticSetterInvoke(
+  R visitStaticSetterInvoke(
       Send node,
       FunctionElement setter,
       NodeList arguments,
@@ -430,7 +432,7 @@
   }
 
   @override
-  R errorSuperSetterGet(
+  R visitSuperSetterGet(
       Send node,
       FunctionElement setter,
       ResolvedKindVisitor<R> visitor) {
@@ -438,7 +440,7 @@
   }
 
   @override
-  R errorSuperSetterInvoke(
+  R visitSuperSetterInvoke(
       Send node,
       FunctionElement setter,
       NodeList arguments,
@@ -448,7 +450,7 @@
   }
 
   @override
-  R errorTopLevelSetterGet(
+  R visitTopLevelSetterGet(
       Send node,
       FunctionElement setter,
       ResolvedKindVisitor<R> visitor) {
@@ -456,7 +458,7 @@
   }
 
   @override
-  R errorTopLevelSetterInvoke(
+  R visitTopLevelSetterInvoke(
       Send node,
       FunctionElement setter,
       NodeList arguments,
@@ -503,7 +505,7 @@
   }
 
   @override
-  R errorUnresolvedPostfix(
+  R visitUnresolvedPostfix(
       Send node,
       Element element,
       op.IncDecOperator operator,
@@ -512,7 +514,7 @@
   }
 
   @override
-  R errorUnresolvedPrefix(
+  R visitUnresolvedPrefix(
       Send node,
       Element element,
       op.IncDecOperator operator,
@@ -575,6 +577,15 @@
   }
 
   @override
+  R visitIfNull(
+      Send node,
+      Node left,
+      Node right,
+      ResolvedKindVisitor<R> visitor) {
+    return visitor.visitOperatorSend(node);
+  }
+
+  @override
   R visitLogicalAnd(
       Send node,
       Node left,
@@ -629,6 +640,16 @@
   }
 
   @override
+  R visitIfNotNullDynamicPropertyInvoke(
+      Send node,
+      Node receiver,
+      NodeList arguments,
+      Selector selector,
+      ResolvedKindVisitor<R> visitor) {
+    return visitor.visitDynamicSend(node);
+  }
+
+  @override
   R visitThisPropertyInvoke(
       Send node,
       NodeList arguments,
diff --git a/pkg/compiler/lib/src/scanner/array_based_scanner.dart b/pkg/compiler/lib/src/scanner/array_based_scanner.dart
index 9fbf715..85e3a3c 100644
--- a/pkg/compiler/lib/src/scanner/array_based_scanner.dart
+++ b/pkg/compiler/lib/src/scanner/array_based_scanner.dart
@@ -5,8 +5,9 @@
 part of scanner;
 
 abstract class ArrayBasedScanner extends AbstractScanner {
-  ArrayBasedScanner(SourceFile file, bool includeComments)
-      : super(file, includeComments);
+  ArrayBasedScanner(SourceFile file, bool includeComments,
+                    bool enableNullAwareOperators)
+      : super(file, includeComments, enableNullAwareOperators);
 
   /**
    * The stack of open groups, e.g [: { ... ( .. :]
@@ -217,4 +218,4 @@
       groupingStack = groupingStack.tail;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/scanner/listener.dart b/pkg/compiler/lib/src/scanner/listener.dart
index 4add7ec..cd747b9 100644
--- a/pkg/compiler/lib/src/scanner/listener.dart
+++ b/pkg/compiler/lib/src/scanner/listener.dart
@@ -695,7 +695,6 @@
                    [Map arguments = const {}]) {
     String message = messageKind.message(arguments, true).toString();
     Token token;
-    Node node;
     if (spannable is Token) {
       token = spannable;
     } else if (spannable is Node) {
@@ -716,7 +715,6 @@
       reportError(
           token, MessageKind.BAD_INPUT_CHARACTER, {'characterHex': hex});
     } else if (token is UnterminatedToken) {
-      String start = token.start;
       MessageKind kind;
       var arguments = const {};
       switch (token.start) {
@@ -748,6 +746,9 @@
           break;
       }
       reportError(token, kind, arguments);
+    } else if (token is UnsupportedNullAwareToken) {
+      reportError(token, MessageKind.NULL_AWARE_OPERATORS_DISABLED,
+          {'operator' : token.operator});
     } else if (token is UnmatchedToken) {
       String begin = token.begin.value;
       String end = closeBraceFor(begin);
@@ -1570,7 +1571,7 @@
       if (name.asSend() == null) {
         name = new Send(thisIdentifier, name);
       } else {
-        name = name.asSend().copyWithReceiver(thisIdentifier);
+        name = name.asSend().copyWithReceiver(thisIdentifier, false);
       }
     }
     TypeAnnotation type = popNode();
@@ -1700,7 +1701,9 @@
     Node argument = popNode();
     Node receiver = popNode();
     String tokenString = token.stringValue;
-    if (identical(tokenString, '.') || identical(tokenString, '..')) {
+    if (identical(tokenString, '.') ||
+        identical(tokenString, '..') ||
+        identical(tokenString, '?.')) {
       Send argumentSend = argument.asSend();
       if (argumentSend == null) {
         // TODO(ahe): The parser should diagnose this problem, not
@@ -1710,7 +1713,8 @@
       }
       if (argumentSend.receiver != null) internalError(node: argument);
       if (argument is SendSet) internalError(node: argument);
-      pushNode(argument.asSend().copyWithReceiver(receiver));
+      pushNode(argument.asSend().copyWithReceiver(receiver,
+            identical(tokenString, '?.')));
     } else {
       NodeList arguments = new NodeList.singleton(argument);
       pushNode(new Send(receiver, new Operator(token), arguments));
@@ -1757,7 +1761,8 @@
       arguments = new NodeList.singleton(arg);
     }
     Operator op = new Operator(token);
-    pushNode(new SendSet(send.receiver, send.selector, op, arguments));
+    pushNode(new SendSet(send.receiver, send.selector, op, arguments,
+        send.isConditional));
   }
 
   void reportNotAssignable(Node node) {
@@ -1924,9 +1929,11 @@
     Operator op = new Operator(token);
 
     if (isPrefix) {
-      pushNode(new SendSet.prefix(send.receiver, send.selector, op, argument));
+      pushNode(new SendSet.prefix(send.receiver, send.selector, op, argument,
+          send.isConditional));
     } else {
-      pushNode(new SendSet.postfix(send.receiver, send.selector, op, argument));
+      pushNode(new SendSet.postfix(send.receiver, send.selector, op, argument,
+          send.isConditional));
     }
   }
 
diff --git a/pkg/compiler/lib/src/scanner/parser.dart b/pkg/compiler/lib/src/scanner/parser.dart
index 7957b5e..10e7dfc 100644
--- a/pkg/compiler/lib/src/scanner/parser.dart
+++ b/pkg/compiler/lib/src/scanner/parser.dart
@@ -399,7 +399,6 @@
   }
 
   Token parseTypeOpt(Token token) {
-    String value = token.stringValue;
     Token peek = peekAfterIfType(token);
     if (peek != null && (peek.isIdentifier() || optional('this', peek))) {
       return parseType(token);
@@ -939,7 +938,6 @@
   ///     ['(', '*', 'operator']
   ///
   Link<Token> findMemberName(Token token) {
-    Token start = token;
     Link<Token> identifiers = const Link<Token>();
 
     // `true` if 'get' has been seen.
@@ -1162,7 +1160,6 @@
 
   Token parseMember(Token token) {
     token = parseMetadataStar(token);
-    String value = token.stringValue;
     if (isFactoryDeclaration(token)) {
       return parseFactoryMethod(token);
     }
@@ -1339,8 +1336,6 @@
     token = token.next; // Skip 'factory'.
     token = parseConstructorReference(token);
     token = parseFormalParameters(token);
-    bool previousYieldIsKeyword = yieldIsKeyword;
-    bool previousAwaitIsKeyword = awaitIsKeyword;
     token = parseAsyncModifier(token);
     if (optional('=', token)) {
       token = parseRedirectingFactoryBody(token);
@@ -1789,7 +1784,8 @@
           token = parsePrecedenceExpression(token.next, level, allowCascades);
           listener.handleAssignmentExpression(operator);
         } else if (identical(tokenLevel, POSTFIX_PRECEDENCE)) {
-          if (identical(info, PERIOD_INFO)) {
+          if (identical(info, PERIOD_INFO) ||
+              identical(info, QUESTION_PERIOD_INFO)) {
             // Left associative, so we recurse at the next higher
             // precedence level. However, POSTFIX_PRECEDENCE is the
             // highest level, so we just call parseUnaryExpression
diff --git a/pkg/compiler/lib/src/scanner/parser_task.dart b/pkg/compiler/lib/src/scanner/parser_task.dart
index af9a013..c680a31 100644
--- a/pkg/compiler/lib/src/scanner/parser_task.dart
+++ b/pkg/compiler/lib/src/scanner/parser_task.dart
@@ -18,7 +18,7 @@
       Parser parser = new Parser(listener);
       try {
         parser.parseUnit(token);
-      } on ParserError catch (e) {
+      } on ParserError catch(_) {
         assert(invariant(token, compiler.compilationFailed));
         return listener.makeNodeList(0, null, null, '\n');
       }
diff --git a/pkg/compiler/lib/src/scanner/scanner.dart b/pkg/compiler/lib/src/scanner/scanner.dart
index 8a38802..65db47e 100644
--- a/pkg/compiler/lib/src/scanner/scanner.dart
+++ b/pkg/compiler/lib/src/scanner/scanner.dart
@@ -7,11 +7,14 @@
 abstract class Scanner {
   Token tokenize();
 
-  factory Scanner(SourceFile file, {bool includeComments: false}) {
+  factory Scanner(SourceFile file,
+      {bool includeComments: false, bool enableNullAwareOperators: false}) {
     if (file is Utf8BytesSourceFile) {
-      return new Utf8BytesScanner(file, includeComments: includeComments);
+      return new Utf8BytesScanner(file, includeComments: includeComments,
+          enableNullAwareOperators: enableNullAwareOperators);
     } else {
-      return new StringScanner(file, includeComments: includeComments);
+      return new StringScanner(file, includeComments: includeComments,
+          enableNullAwareOperators: enableNullAwareOperators);
     }
   }
 }
@@ -20,6 +23,7 @@
   // TODO(ahe): Move this class to implementation.
 
   final bool includeComments;
+  final bool enableNullAwareOperators;
 
   /**
    * The string offset for the next token that will be created.
@@ -53,7 +57,8 @@
 
   final List<int> lineStarts = <int>[0];
 
-  AbstractScanner(this.file, this.includeComments) {
+  AbstractScanner(
+      this.file, this.includeComments, this.enableNullAwareOperators) {
     this.tail = this.tokens;
   }
 
@@ -330,8 +335,7 @@
     }
 
     if (identical(next, $QUESTION)) {
-      appendPrecedenceToken(QUESTION_INFO);
-      return advance();
+      return tokenizeQuestion(next);
     }
 
     if (identical(next, $CLOSE_SQUARE_BRACKET)) {
@@ -450,6 +454,38 @@
     return select($EQ, CARET_EQ_INFO, CARET_INFO);
   }
 
+  int tokenizeQuestion(int next) {
+    // ? ?. ?? ??=
+    next = advance();
+    if (identical(next, $QUESTION)) {
+      if (enableNullAwareOperators) {
+        return select($EQ, QUESTION_QUESTION_EQ_INFO, QUESTION_QUESTION_INFO);
+      } else {
+        next = advance();
+        PrecedenceInfo info;
+        if (identical(next, $EQ)) {
+          info = QUESTION_QUESTION_EQ_INFO;
+          next = advance();
+        } else {
+          info = QUESTION_QUESTION_INFO;
+        }
+        appendErrorToken(new UnsupportedNullAwareToken(info.value, tokenStart));
+        return next;
+      }
+    } else if (identical(next, $PERIOD)) {
+      if (enableNullAwareOperators) {
+        appendPrecedenceToken(QUESTION_PERIOD_INFO);
+      } else {
+        appendErrorToken(new UnsupportedNullAwareToken(
+            QUESTION_PERIOD_INFO.value, tokenStart));
+      }
+      return advance();
+    } else {
+      appendPrecedenceToken(QUESTION_INFO);
+      return next;
+    }
+  }
+
   int tokenizeBar(int next) {
     // | || |=
     next = advance();
diff --git a/pkg/compiler/lib/src/scanner/scanner_task.dart b/pkg/compiler/lib/src/scanner/scanner_task.dart
index ac560cb..e239026 100644
--- a/pkg/compiler/lib/src/scanner/scanner_task.dart
+++ b/pkg/compiler/lib/src/scanner/scanner_task.dart
@@ -29,7 +29,8 @@
   void scanElements(CompilationUnitElement compilationUnit) {
     Script script = compilationUnit.script;
     Token tokens = new Scanner(script.file,
-        includeComments: compiler.preserveComments).tokenize();
+        includeComments: compiler.preserveComments,
+        enableNullAwareOperators: compiler.enableNullAwareOperators).tokenize();
     if (compiler.preserveComments) {
       tokens = compiler.processAndStripComments(tokens);
     }
@@ -63,7 +64,7 @@
       PartialParser parser = new PartialParser(listener);
       try {
         parser.parseUnit(tokens);
-      } on ParserError catch (e) {
+      } on ParserError catch(_) {
         assert(invariant(compilationUnit, compiler.compilationFailed));
       }
     });
diff --git a/pkg/compiler/lib/src/scanner/string_scanner.dart b/pkg/compiler/lib/src/scanner/string_scanner.dart
index 5a30e43..8eb736f 100644
--- a/pkg/compiler/lib/src/scanner/string_scanner.dart
+++ b/pkg/compiler/lib/src/scanner/string_scanner.dart
@@ -15,14 +15,16 @@
   /** The current offset in [string]. */
   int scanOffset = -1;
 
-  StringScanner(SourceFile file, {bool includeComments: false})
+  StringScanner(SourceFile file, {bool includeComments: false,
+                                  bool enableNullAwareOperators: false})
       : string = file.slowText(),
-        super(file, includeComments) {
+        super(file, includeComments, enableNullAwareOperators) {
     ensureZeroTermination();
   }
 
-  StringScanner.fromString(this.string, {bool includeComments: false})
-      : super(null, includeComments) {
+  StringScanner.fromString(this.string, {bool includeComments: false,
+                                         bool enableNullAwareOperators: false})
+      : super(null, includeComments, enableNullAwareOperators) {
     ensureZeroTermination();
   }
 
diff --git a/pkg/compiler/lib/src/scanner/token.dart b/pkg/compiler/lib/src/scanner/token.dart
index 76229cd..c1a502b 100644
--- a/pkg/compiler/lib/src/scanner/token.dart
+++ b/pkg/compiler/lib/src/scanner/token.dart
@@ -75,6 +75,9 @@
 const int CARET_EQ_TOKEN = GT_GT_TOKEN + 1;
 const int COMMENT_TOKEN = CARET_EQ_TOKEN + 1;
 const int STRING_INTERPOLATION_IDENTIFIER_TOKEN = COMMENT_TOKEN + 1;
+const int QUESTION_PERIOD_TOKEN = STRING_INTERPOLATION_IDENTIFIER_TOKEN + 1;
+const int QUESTION_QUESTION_TOKEN = QUESTION_PERIOD_TOKEN + 1;
+const int QUESTION_QUESTION_EQ_TOKEN = QUESTION_QUESTION_TOKEN + 1;
 
 /**
  * A token that doubles as a linked list.
@@ -259,6 +262,21 @@
   }
 }
 
+// TODO(sigmund): delete once we enable null-aware-operators by default.
+class UnsupportedNullAwareToken extends ErrorToken {
+  final String operator;
+
+  UnsupportedNullAwareToken(this.operator, int charOffset)
+      : super(charOffset);
+
+  String toString() => "UnsupportedNullAwareToken($operator)";
+
+  String get assertionMessage => "'$operator' isn't supported without "
+      "the --enable-null-aware-operators flag.";
+
+  int get charCount => operator.length;
+}
+
 class UnterminatedToken extends ErrorToken {
   final String start;
   final int endOffset;
@@ -589,27 +607,33 @@
 const PrecedenceInfo TILDE_SLASH_EQ_INFO =
   const PrecedenceInfo('~/=',
                        ASSIGNMENT_PRECEDENCE, TILDE_SLASH_EQ_TOKEN);
+const PrecedenceInfo QUESTION_QUESTION_EQ_INFO =
+  const PrecedenceInfo('??=',
+                       ASSIGNMENT_PRECEDENCE, QUESTION_QUESTION_EQ_TOKEN);
 
 const PrecedenceInfo QUESTION_INFO =
   const PrecedenceInfo('?', 3, QUESTION_TOKEN);
 
+const PrecedenceInfo QUESTION_QUESTION_INFO =
+  const PrecedenceInfo('??', 4, QUESTION_QUESTION_TOKEN);
+
 const PrecedenceInfo BAR_BAR_INFO =
-  const PrecedenceInfo('||', 4, BAR_BAR_TOKEN);
+  const PrecedenceInfo('||', 5, BAR_BAR_TOKEN);
 
 const PrecedenceInfo AMPERSAND_AMPERSAND_INFO =
-  const PrecedenceInfo('&&', 5, AMPERSAND_AMPERSAND_TOKEN);
+  const PrecedenceInfo('&&', 6, AMPERSAND_AMPERSAND_TOKEN);
 
 const PrecedenceInfo BAR_INFO =
-  const PrecedenceInfo('|', 8, BAR_TOKEN);
+  const PrecedenceInfo('|', 9, BAR_TOKEN);
 
 const PrecedenceInfo CARET_INFO =
-  const PrecedenceInfo('^', 9, CARET_TOKEN);
+  const PrecedenceInfo('^', 10, CARET_TOKEN);
 
 const PrecedenceInfo AMPERSAND_INFO =
-  const PrecedenceInfo('&', 10, AMPERSAND_TOKEN);
+  const PrecedenceInfo('&', 11, AMPERSAND_TOKEN);
 
 // Equality operators.
-const int EQUALITY_PRECEDENCE = 6;
+const int EQUALITY_PRECEDENCE = 7;
 const PrecedenceInfo BANG_EQ_EQ_INFO =
   const PrecedenceInfo('!==',
                        EQUALITY_PRECEDENCE, BANG_EQ_EQ_TOKEN);
@@ -624,7 +648,7 @@
                        EQUALITY_PRECEDENCE, EQ_EQ_TOKEN);
 
 // Relational operators.
-const int RELATIONAL_PRECEDENCE = 7;
+const int RELATIONAL_PRECEDENCE = 8;
 const PrecedenceInfo GT_EQ_INFO =
   const PrecedenceInfo('>=',
                        RELATIONAL_PRECEDENCE, GT_EQ_TOKEN);
@@ -646,30 +670,33 @@
 
 // Shift operators.
 const PrecedenceInfo GT_GT_INFO =
-  const PrecedenceInfo('>>', 11, GT_GT_TOKEN);
+  const PrecedenceInfo('>>', 12, GT_GT_TOKEN);
 const PrecedenceInfo LT_LT_INFO =
-  const PrecedenceInfo('<<', 11, LT_LT_TOKEN);
+  const PrecedenceInfo('<<', 12, LT_LT_TOKEN);
 
 // Additive operators.
 const PrecedenceInfo MINUS_INFO =
-  const PrecedenceInfo('-', 12, MINUS_TOKEN);
+  const PrecedenceInfo('-', 13, MINUS_TOKEN);
 const PrecedenceInfo PLUS_INFO =
-  const PrecedenceInfo('+', 12, PLUS_TOKEN);
+  const PrecedenceInfo('+', 13, PLUS_TOKEN);
 
 // Multiplicative operators.
 const PrecedenceInfo PERCENT_INFO =
-  const PrecedenceInfo('%', 13, PERCENT_TOKEN);
+  const PrecedenceInfo('%', 14, PERCENT_TOKEN);
 const PrecedenceInfo SLASH_INFO =
-  const PrecedenceInfo('/', 13, SLASH_TOKEN);
+  const PrecedenceInfo('/', 14, SLASH_TOKEN);
 const PrecedenceInfo STAR_INFO =
-  const PrecedenceInfo('*', 13, STAR_TOKEN);
+  const PrecedenceInfo('*', 14, STAR_TOKEN);
 const PrecedenceInfo TILDE_SLASH_INFO =
-  const PrecedenceInfo('~/', 13, TILDE_SLASH_TOKEN);
+  const PrecedenceInfo('~/', 14, TILDE_SLASH_TOKEN);
 
-const int POSTFIX_PRECEDENCE = 14;
+const int POSTFIX_PRECEDENCE = 15;
 const PrecedenceInfo PERIOD_INFO =
   const PrecedenceInfo('.', POSTFIX_PRECEDENCE,
                        PERIOD_TOKEN);
+const PrecedenceInfo QUESTION_PERIOD_INFO =
+  const PrecedenceInfo('?.', POSTFIX_PRECEDENCE,
+                       QUESTION_PERIOD_TOKEN);
 
 const PrecedenceInfo KEYWORD_INFO =
   const PrecedenceInfo('keyword', 0, KEYWORD_TOKEN);
diff --git a/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart b/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart
index d919596..f242f57 100644
--- a/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart
+++ b/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart
@@ -69,9 +69,10 @@
    * array whose last element is '0' to signal the end of the file. If this
    * is not the case, the entire array is copied before scanning.
    */
-  Utf8BytesScanner(SourceFile file, {bool includeComments: false})
+  Utf8BytesScanner(SourceFile file, {bool includeComments: false,
+                                     bool enableNullAwareOperators: false})
       : bytes = file.slowUtf8ZeroTerminatedBytes(),
-        super(file, includeComments) {
+        super(file, includeComments, enableNullAwareOperators) {
     assert(bytes.last == 0);
     // Skip a leading BOM.
     if (_containsBomAt(0)) byteOffset += 3;
@@ -85,9 +86,10 @@
    * scanning.
    */
   Utf8BytesScanner.fromBytes(List<int> zeroTerminatedBytes,
-                             {bool includeComments: false})
+                             {bool includeComments: false,
+                              bool enableNullAwareOperators: false})
       : this.bytes = zeroTerminatedBytes,
-        super(null, includeComments) {
+        super(null, includeComments, enableNullAwareOperators) {
     assert(bytes.last == 0);
   }
 
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index d0bd1b9..30a7559 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -22,7 +22,7 @@
   var length = file.lengthSync();
   // +1 to have a 0 terminated list, see [Scanner].
   var buffer = new Uint8List(length + 1);
-  var bytes = file.readIntoSync(buffer, 0, length);
+  file.readIntoSync(buffer, 0, length);
   file.closeSync();
   return buffer;
 }
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 2dca503..310a5c7 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -1362,6 +1362,11 @@
       return true;
     }
 
+    bool doesNotContainCode() {
+      // A function with size 1 does not contain any code.
+      return InlineWeeder.canBeInlined(function, 1, true);
+    }
+
     bool reductiveHeuristic() {
       // The call is on a path which is executed rarely, so inline only if it
       // does not make the program larger.
@@ -1375,12 +1380,7 @@
       // 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 InlineWeeder.canBeInlined(function, 1, true);
-    }
-
-    bool doesNotContainCode() {
-      // A function with size 1 does not contain any code.
-      return InlineWeeder.canBeInlined(function, 1, true);
+      return doesNotContainCode();
     }
 
     bool heuristicSayGoodToGo() {
@@ -1827,7 +1827,7 @@
    *
    * Invariant: [constructors] must contain only implementation elements.
    */
-  void inlineSuperOrRedirect(FunctionElement callee,
+  void inlineSuperOrRedirect(ConstructorElement callee,
                              List<HInstruction> compiledArguments,
                              List<FunctionElement> constructors,
                              Map<Element, HInstruction> fieldValues,
@@ -1869,9 +1869,9 @@
         }
       }
 
-      // For redirecting constructors, the fields have already been
-      // initialized by the caller.
-      if (callee.enclosingClass != caller.enclosingClass) {
+      // For redirecting constructors, the fields will be initialized later
+      // by the effective target.
+      if (!callee.isRedirectingGenerative) {
         inlinedFrom(callee, () {
           buildFieldInitializers(callee.enclosingElement.implementation,
                                fieldValues);
@@ -2074,7 +2074,7 @@
    *  - Call the constructor bodies, starting from the constructor(s) in the
    *    super class(es).
    */
-  HGraph buildFactory(FunctionElement functionElement) {
+  HGraph buildFactory(ConstructorElement functionElement) {
     functionElement = functionElement.implementation;
     ClassElement classElement =
         functionElement.enclosingClass.implementation;
@@ -2093,8 +2093,11 @@
     Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>();
 
     // Compile the possible initialization code for local fields and
-    // super fields.
-    buildFieldInitializers(classElement, fieldValues);
+    // 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;
@@ -3139,6 +3142,12 @@
   }
 
   @override
+  void visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) {
+    SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
+    brancher.handleIfNull(() => visit(left), () => visit(right));
+  }
+
+  @override
   void visitLogicalAnd(ast.Send node, ast.Node left, ast.Node right, _) {
     SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
     branchBuilder.handleLogicalAndOrWithLeftNode(
@@ -3289,7 +3298,7 @@
           argumentNodes: const Link<ast.Node>());
     } else {
       // This happens when [element] has parse errors.
-      assert(invariant(node, element.isErroneous));
+      assert(invariant(node, element == null || element.isErroneous));
       // TODO(ahe): Do something like the above, that is, emit a runtime
       // error.
       stack.add(graph.addConstantNull(compiler));
@@ -3395,6 +3404,36 @@
   }
 
   @override
+  void visitIfNotNullDynamicPropertyGet(
+      ast.Send node,
+      ast.Node receiver,
+      Selector selector,
+      _) {
+    // 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), expression));
+  }
+
+  /// Pushes a boolean checking [expression] against null.
+  pushCheckNull(HInstruction expression) {
+    push(new HIdentity(expression, graph.addConstantNull(compiler),
+          null, backend.boolType));
+  }
+
+  @override
   void visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) {
     handleLocalGet(variable);
   }
@@ -3465,6 +3504,37 @@
     generateStaticGetterGet(node, getter);
   }
 
+  void generatePossiblyConditionalInstanceSetter(ast.Send send,
+                                                 HInstruction pushReceiver(),
+                                                 HInstruction pushValue(),
+                                                 {Selector selector,
+                                                  ast.Node location}) {
+    if (send.isConditional) {
+      SsaBranchBuilder brancher = new SsaBranchBuilder(this, send);
+      // compile e?.x = e2 to:
+      //
+      // t1 = e
+      // if (t1 == null)
+      //   result = t1 // same as result = null
+      // else
+      //   result = e.x = e2
+      HInstruction receiver;
+      brancher.handleConditional(
+          () {
+            receiver = pushReceiver();
+            pushCheckNull(receiver);
+          },
+          () => stack.add(receiver),
+          () => generateInstanceSetterWithCompiledReceiver(
+                    send, receiver, pushValue(),
+                    selector: selector, location: location));
+    } else {
+      generateInstanceSetterWithCompiledReceiver(
+          send, pushReceiver(), pushValue(),
+          selector: selector, location: location);
+    }
+  }
+
   void generateInstanceSetterWithCompiledReceiver(ast.Send send,
                                                   HInstruction receiver,
                                                   HInstruction value,
@@ -3556,17 +3626,17 @@
       InterfaceType interface = type;
       List<HInstruction> inputs = <HInstruction>[];
       bool first = true;
-      List<String> templates = <String>[];
+      List<js.Expression> templates = <js.Expression>[];
       for (DartType argument in interface.typeArguments) {
-        templates.add(rti.getTypeRepresentationWithHashes(argument, (variable) {
+        templates.add(rti.getTypeRepresentationWithPlaceholders(argument, (variable) {
           HInstruction runtimeType = addTypeVariableReference(variable);
           inputs.add(runtimeType);
-        }));
+        }, firstPlaceholderIndex : inputs.length));
       }
-      String template = '[${templates.join(', ')}]';
       // TODO(sra): This is a fresh template each time.  We can't let the
       // template manager build them.
-      js.Template code = js.js.uncachedExpressionTemplate(template);
+      js.Template code = new js.Template(null,
+                                         new js.ArrayInitializer(templates));
       HInstruction representation =
           new HForeignCode(code, backend.readableArrayType, inputs,
               nativeBehavior: native.NativeBehavior.PURE_ALLOCATION);
@@ -3727,10 +3797,14 @@
 
   /// 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);
 
     List<HInstruction> inputs = <HInstruction>[];
-    HInstruction receiver = generateInstanceSendReceiver(node);
     inputs.add(receiver);
     addDynamicSendArgumentsToList(node, inputs);
 
@@ -3752,6 +3826,25 @@
   }
 
   @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,
@@ -4165,14 +4258,6 @@
       handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF');
     } else if (name == 'JS_SET_CURRENT_ISOLATE') {
       handleForeignSetCurrentIsolate(node);
-    } else if (name == 'JS_OBJECT_CLASS_NAME') {
-      // TODO(floitsch): this should be a JS_NAME.
-      String name = backend.namer.runtimeTypeName(compiler.objectClass);
-      stack.add(addConstantString(name));
-    } else if (name == 'JS_NULL_CLASS_NAME') {
-      // TODO(floitsch): this should be a JS_NAME.
-      String name = backend.namer.runtimeTypeName(compiler.nullClass);
-      stack.add(addConstantString(name));
     } else if (name == 'JS_OPERATOR_AS_PREFIX') {
       // TODO(floitsch): this should be a JS_NAME.
       stack.add(addConstantString(backend.namer.operatorAsPrefix));
@@ -4483,6 +4568,16 @@
   }
 
   @override
+  void visitSuperNotEquals(
+      ast.Send node,
+      MethodElement method,
+      ast.Node argument,
+      _) {
+    handleSuperMethodInvoke(node, method);
+    pushWithPosition(new HNot(popBoolified(), backend.boolType), node.selector);
+  }
+
+  @override
   void visitSuperUnary(
       ast.Send node,
       UnaryOperator operator,
@@ -4623,11 +4718,12 @@
 
     List<HInstruction> inputs = <HInstruction>[];
 
-    String template = rti.getTypeRepresentationWithHashes(argument, (variable) {
-      inputs.add(addTypeVariableReference(variable));
-    });
+    js.Expression template =
+        rti.getTypeRepresentationWithPlaceholders(argument, (variable) {
+            inputs.add(addTypeVariableReference(variable));
+        });
 
-    js.Template code = js.js.uncachedExpressionTemplate(template);
+    js.Template code = new js.Template(null, template);
     HInstruction result = new HForeignCode(code, backend.stringType, inputs,
         nativeBehavior: native.NativeBehavior.PURE);
     add(result);
@@ -5509,11 +5605,22 @@
     }
     ast.Operator op = node.assignmentOperator;
     if (node.isSuperCall) {
-      HInstruction result;
       List<HInstruction> setterInputs = <HInstruction>[];
+      void generateSuperSendSet() {
+        Selector setterSelector = elements.getSelector(node);
+        if (Elements.isUnresolved(element)
+            || !setterSelector.applies(element, compiler.world)) {
+          generateSuperNoSuchMethodSend(
+              node, setterSelector, setterInputs);
+          pop();
+        } else {
+          add(buildInvokeSuper(setterSelector, element, setterInputs));
+        }
+      }
       if (identical(node.assignmentOperator.source, '=')) {
         addDynamicSendArgumentsToList(node, setterInputs);
-        result = setterInputs.last;
+        generateSuperSendSet();
+        stack.add(setterInputs.last);
       } else {
         Element getter = elements[node.selector];
         List<HInstruction> getterInputs = <HInstruction>[];
@@ -5543,25 +5650,22 @@
               getterSelector, getter, getterInputs);
           add(getterInstruction);
         }
-        handleComplexOperatorSend(node, getterInstruction, arguments);
-        setterInputs.add(pop());
 
-        if (node.isPostfix) {
-          result = getterInstruction;
+        if (node.isIfNullAssignment) {
+          SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
+          brancher.handleIfNull(() => stack.add(getterInstruction),
+              () {
+                addDynamicSendArgumentsToList(node, setterInputs);
+                generateSuperSendSet();
+                stack.add(setterInputs.last);
+              });
         } else {
-          result = setterInputs.last;
+          handleComplexOperatorSend(node, getterInstruction, arguments);
+          setterInputs.add(pop());
+          generateSuperSendSet();
+          stack.add(node.isPostfix ? getterInstruction : setterInputs.last);
         }
       }
-      Selector setterSelector = elements.getSelector(node);
-      if (Elements.isUnresolved(element)
-          || !setterSelector.applies(element, compiler.world)) {
-        generateSuperNoSuchMethodSend(
-            node, setterSelector, setterInputs);
-        pop();
-      } else {
-        add(buildInvokeSuper(setterSelector, element, setterInputs));
-      }
-      stack.add(result);
     } else if (node.isIndex) {
       if ("=" == op.source) {
         generateDynamicSend(node);
@@ -5581,27 +5685,42 @@
             elements.getGetterSelectorInComplexSendSet(node),
             [receiver, index]);
         HInstruction getterInstruction = pop();
-
-        handleComplexOperatorSend(node, getterInstruction, arguments);
-        HInstruction value = pop();
-
-        pushInvokeDynamic(
-            node, elements.getSelector(node), [receiver, index, value]);
-        pop();
-
-        if (node.isPostfix) {
-          stack.add(getterInstruction);
+        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), [receiver, index, value]);
+                pop();
+                stack.add(value);
+              });
         } else {
-          stack.add(value);
+          handleComplexOperatorSend(node, getterInstruction, arguments);
+          HInstruction value = pop();
+          pushInvokeDynamic(
+              node, elements.getSelector(node), [receiver, index, value]);
+          pop();
+          if (node.isPostfix) {
+            stack.add(getterInstruction);
+          } else {
+            stack.add(value);
+          }
         }
       }
     } else if ("=" == op.source) {
       Link<ast.Node> link = node.arguments;
       assert(!link.isEmpty && link.tail.isEmpty);
       if (Elements.isInstanceSend(node, elements)) {
-        HInstruction receiver = generateInstanceSendReceiver(node);
-        visit(link.head);
-        generateInstanceSetterWithCompiledReceiver(node, receiver, pop());
+        generatePossiblyConditionalInstanceSetter(node,
+            () => generateInstanceSendReceiver(node),
+            () => visitAndPop(link.head));
       } else {
         visit(link.head);
         generateNonInstanceSetter(node, element, pop());
@@ -5612,20 +5731,64 @@
       assert("++" == op.source || "--" == op.source ||
              node.assignmentOperator.source.endsWith("="));
 
-      // [receiver] is only used if the node is an instance send.
-      HInstruction receiver = null;
       Element getter = elements[node.selector];
 
       if (!Elements.isUnresolved(getter) && getter.impliesType) {
-        ast.Identifier selector = node.selector;
-        generateThrowNoSuchMethod(node, selector.source,
-                                  argumentNodes: node.arguments);
+        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;
-      } else if (Elements.isInstanceSend(node, elements)) {
-        receiver = generateInstanceSendReceiver(node);
-        generateInstanceGetterWithCompiledReceiver(
-            node, elements.getGetterSelectorInComplexSendSet(node), receiver);
-      } else if (getter.isErroneous) {
+      }
+
+      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), 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.isErroneous) {
         generateStaticUnresolvedGet(node, getter);
       } else if (getter.isField) {
         generateStaticFieldGet(node, getter);
@@ -5639,14 +5802,16 @@
         internalError(node, "Unexpected getter: $getter");
       }
       HInstruction getterInstruction = pop();
-      handleComplexOperatorSend(node, getterInstruction, node.arguments);
-      HInstruction value = pop();
-      assert(value != null);
-      if (Elements.isInstanceSend(node, elements)) {
-        assert(receiver != null);
-        generateInstanceSetterWithCompiledReceiver(node, receiver, value);
+      if (node.isIfNullAssignment) {
+        SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
+        brancher.handleIfNull(() => stack.add(getterInstruction),
+            () {
+              visit(node.arguments.head);
+              generateNonInstanceSetter(node, element, pop());
+            });
       } else {
-        assert(receiver == null);
+        handleComplexOperatorSend(node, getterInstruction, node.arguments);
+        HInstruction value = pop();
         generateNonInstanceSetter(node, element, value);
       }
       if (node.isPostfix) {
@@ -7455,6 +7620,19 @@
     _handleDiamondBranch(visitCondition, visitThen, visitElse, true);
   }
 
+  handleIfNull(void left(), void right()) {
+    // x ?? y is transformed into: x == null ? y : x
+    HInstruction leftExpression;
+    handleConditional(
+        () {
+          left();
+          leftExpression = builder.pop();
+          builder.pushCheckNull(leftExpression);
+        },
+        right,
+        () => builder.stack.add(leftExpression));
+  }
+
   void handleLogicalAndOr(void left(), void right(), {bool isAnd}) {
     // x && y is transformed into:
     //   t0 = boolify(x);
@@ -7558,8 +7736,6 @@
       builder.stack.add(phi);
     }
 
-    HBasicBlock thenBlock = thenBranch.block;
-    HBasicBlock elseBlock = elseBranch.block;
     HBasicBlock joinBlock;
     // If at least one branch did not abort, open the joinBranch.
     if (!joinBranch.block.predecessors.isEmpty) {
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index c8cfebc..dbc5e5f 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -142,7 +142,6 @@
 
   HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                    Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
     HInstruction input = instruction.inputs[1];
     if (input.isNumber(compiler)) {
       return new HBitNot(input, instruction.selector,
@@ -417,7 +416,6 @@
 
   HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                    Compiler compiler) {
-    HInstruction left = instruction.inputs[1];
     HInstruction right = instruction.inputs[2];
     if (isBuiltin(instruction, compiler)) {
       if (right.isPositiveInteger(compiler) && isNotZero(right, compiler)) {
@@ -491,7 +489,6 @@
       // the instruction does not have any side effect, and that it
       // can be GVN'ed.
       clearAllSideEffects(instruction);
-      Selector selector = instruction.selector;
       if (isPositive(right, compiler)) {
         instruction.selector = renameToOptimizedSelector(
             '_shlPositive', instruction.selector, compiler);
@@ -502,7 +499,6 @@
 
   HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                  Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
     return new HShiftLeft(
         instruction.inputs[1], instruction.inputs[2],
         instruction.selector, computeTypeFromInputTypes(instruction, compiler));
@@ -515,8 +511,6 @@
   TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
                                      Compiler compiler) {
     HInstruction left = instruction.inputs[1];
-    HInstruction right = instruction.inputs[2];
-    JavaScriptBackend backend = compiler.backend;
     if (left.isUInt32(compiler)) return left.instructionType;
     return super.computeTypeFromInputTypes(instruction, compiler);
   }
@@ -549,7 +543,6 @@
 
   HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                  Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
     return new HShiftRight(
         instruction.inputs[1], instruction.inputs[2],
         instruction.selector, computeTypeFromInputTypes(instruction, compiler));
@@ -580,7 +573,6 @@
 
   HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                  Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
     return new HBitOr(
         instruction.inputs[1], instruction.inputs[2],
         instruction.selector, computeTypeFromInputTypes(instruction, compiler));
@@ -608,7 +600,6 @@
 
   HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                  Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
     return new HBitAnd(
         instruction.inputs[1], instruction.inputs[2],
         instruction.selector, computeTypeFromInputTypes(instruction, compiler));
@@ -635,7 +626,6 @@
 
   HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                  Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
     return new HBitXor(
         instruction.inputs[1], instruction.inputs[2],
         instruction.selector, computeTypeFromInputTypes(instruction, compiler));
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 1529104..953a6f4 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -264,8 +264,17 @@
       }
       Element element = backend.jsIndexableLength;
       bool isFixed = isFixedLength(actualReceiver.instructionType, compiler);
+      TypeMask actualType = node.instructionType;
+      ClassWorld classWorld = compiler.world;
+      TypeMask resultType = backend.positiveIntType;
+      // If we already have computed a more specific type, keep that type.
+      if (actualType.satisfies(backend.jsUInt31Class, classWorld)) {
+        resultType = backend.uint31Type;
+      } else if (actualType.satisfies(backend.jsUInt32Class, classWorld)) {
+        resultType = backend.uint32Type;
+      }
       HFieldGet result = new HFieldGet(
-          element, actualReceiver, backend.positiveIntType,
+          element, actualReceiver, resultType,
           isAssignable: !isFixed);
       return result;
     } else if (actualReceiver.isConstantMap()) {
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 71abe6c..0aa5f0f 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -343,10 +343,10 @@
     }
 
     HInstruction receiver = instruction.getDartReceiver(compiler);
-    TypeMask receiverType = receiver.instructionType;
-    Selector selector =
-        new TypedSelector(receiverType, instruction.selector, classWorld);
-    instruction.selector = selector;
+    Selector selector = instruction.selector;
+    TypeMask receiverType = selector is TypedSelector
+        ? selector.mask.intersection(receiver.instructionType, classWorld)
+        : receiver.instructionType;
 
     // Try to specialize the receiver after this call.
     if (receiver.dominatedUsers(instruction).length != 1
diff --git a/pkg/compiler/lib/src/string_validator.dart b/pkg/compiler/lib/src/string_validator.dart
index 5a7c331..6b519f3 100644
--- a/pkg/compiler/lib/src/string_validator.dart
+++ b/pkg/compiler/lib/src/string_validator.dart
@@ -48,7 +48,6 @@
     // 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.
-    bool multiline = false;
     if (source.moveNext() && source.current == quoteChar && source.moveNext()) {
       int code = source.current;
       assert(code == quoteChar);  // If not, there is a bug in the parser.
@@ -155,7 +154,6 @@
           // A two-byte hex escape can't generate an invalid value.
           continue;
         } else if (code == $u) {
-          int escapeStart = index - 1;
           index++;
           code = iter.hasNext ? iter.next() : 0;
           int value = 0;
diff --git a/pkg/compiler/lib/src/tree/nodes.dart b/pkg/compiler/lib/src/tree/nodes.dart
index d6222eb..6461256 100644
--- a/pkg/compiler/lib/src/tree/nodes.dart
+++ b/pkg/compiler/lib/src/tree/nodes.dart
@@ -357,14 +357,21 @@
   final Node receiver;
   final Node selector;
   final NodeList argumentsNode;
+
+  /// Whether this is a conditinal send of the form `a?.b`.
+  final bool isConditional;
+
   Link<Node> get arguments => argumentsNode.nodes;
 
-  Send([this.receiver, this.selector, this.argumentsNode]);
-  Send.postfix(this.receiver, this.selector, [Node argument = null])
+  Send([this.receiver, this.selector, this.argumentsNode,
+      this.isConditional = false]);
+  Send.postfix(this.receiver, this.selector,
+      [Node argument = null, this.isConditional = false])
       : argumentsNode = (argument == null)
         ? new Postfix()
         : new Postfix.singleton(argument);
-  Send.prefix(this.receiver, this.selector, [Node argument = null])
+  Send.prefix(this.receiver, this.selector,
+      [Node argument = null, this.isConditional = false])
       : argumentsNode = (argument == null)
         ? new Prefix()
         : new Prefix.singleton(argument);
@@ -398,6 +405,8 @@
       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
@@ -441,9 +450,9 @@
     return getBeginToken();
   }
 
-  Send copyWithReceiver(Node newReceiver) {
+  Send copyWithReceiver(Node newReceiver, bool isConditional) {
     assert(receiver == null);
-    return new Send(newReceiver, selector, argumentsNode);
+    return new Send(newReceiver, selector, argumentsNode, isConditional);
   }
 }
 
@@ -459,32 +468,37 @@
 
 class SendSet extends Send {
   final Operator assignmentOperator;
-  SendSet(receiver, selector, this.assignmentOperator, argumentsNode)
-    : super(receiver, selector, argumentsNode);
+  SendSet(receiver, selector, this.assignmentOperator, argumentsNode,
+      [bool isConditional = false])
+    : super(receiver, selector, argumentsNode, isConditional);
   SendSet.postfix(receiver,
                   selector,
                   this.assignmentOperator,
-                  [Node argument = null])
-      : super.postfix(receiver, selector, argument);
+                  [Node argument = null, bool isConditional = false])
+      : super.postfix(receiver, selector, argument, isConditional);
   SendSet.prefix(receiver,
                  selector,
                  this.assignmentOperator,
-                 [Node argument = null])
-      : super.prefix(receiver, selector, argument);
+                 [Node argument = null, bool isConditional = false])
+      : super.prefix(receiver, selector, argument, isConditional);
 
   SendSet asSendSet() => this;
 
   accept(Visitor visitor) => visitor.visitSendSet(this);
 
+  /// Whether this is an if-null assignment of the form `a ??= b`.
+  bool get isIfNullAssignment =>
+      identical(assignmentOperator.source, '??=');
+
   visitChildren(Visitor visitor) {
     super.visitChildren(visitor);
     if (assignmentOperator != null) assignmentOperator.accept(visitor);
   }
 
-  Send copyWithReceiver(Node newReceiver) {
+  Send copyWithReceiver(Node newReceiver, bool isConditional) {
     assert(receiver == null);
     return new SendSet(newReceiver, selector, assignmentOperator,
-                       argumentsNode);
+                       argumentsNode, isConditional);
   }
 
   Token getBeginToken() {
@@ -1047,7 +1061,7 @@
 class Operator extends Identifier {
   static const COMPLEX_OPERATORS =
       const ["--", "++", '+=', "-=", "*=", "/=", "%=", "&=", "|=", "~/=", "^=",
-             ">>=", "<<="];
+             ">>=", "<<=", "??="];
 
   static const INCREMENT_OPERATORS = const <String>["++", "--"];
 
@@ -2250,6 +2264,7 @@
     return (node.receiver == null && node.selector.isSuper()) ||
            (node.receiver != null &&
             node.receiver.isSuper() &&
+            !node.isConditional &&
             node.selector.asIdentifier() != null);
   }
 
@@ -2257,6 +2272,7 @@
     return (node.receiver == null && node.selector.isThis()) ||
            (node.receiver != null &&
             node.receiver.isThis() &&
+            !node.isConditional &&
             node.selector.asIdentifier() != null);
   }
 }
diff --git a/pkg/compiler/lib/src/tree/unparser.dart b/pkg/compiler/lib/src/tree/unparser.dart
index 5325f13..b7d3109 100644
--- a/pkg/compiler/lib/src/tree/unparser.dart
+++ b/pkg/compiler/lib/src/tree/unparser.dart
@@ -68,8 +68,6 @@
       indentMore();
       newline();
       visit(nodes.head);
-      String delimiter =
-        (statements.delimiter == null) ? "" : "${statements.delimiter}";
       for (Link link = nodes.tail; !link.isEmpty; link = link.tail) {
         newline();
         visit(link.head);
@@ -426,7 +424,7 @@
       indentLess();
       indentLess();
     } else if (node.selector.asOperator() == null) {
-      write('.');
+      write(node.isConditional ? '?.' : '.');
     } else if (spacesNeeded) {
       write(' ');
     }
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/pull_into_initializers.dart b/pkg/compiler/lib/src/tree_ir/optimization/pull_into_initializers.dart
index 4719b6a..e68c488 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/pull_into_initializers.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/pull_into_initializers.dart
@@ -247,7 +247,9 @@
   }
 
   Expression visitTypeOperator(TypeOperator node) {
-    node.receiver = visitExpression(node.receiver);
+    node.value = visitExpression(node.value);
+    if (seenImpure) return node;
+    rewriteList(node.typeArguments);
     if (!node.isTypeTest) seenImpure = true; // Type cast can throw.
     return node;
   }
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
index 643aeb2..f845e43 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -343,41 +343,38 @@
     return node;
   }
 
-  Expression visitInvokeStatic(InvokeStatic node) {
-    // Process arguments right-to-left, the opposite of evaluation order.
-    for (int i = node.arguments.length - 1; i >= 0; --i) {
-      node.arguments[i] = visitExpression(node.arguments[i]);
+  /// Process nodes right-to-left, the opposite of evaluation order in the case
+  /// of argument lists..
+  void _rewriteList(List<Node> nodes) {
+    for (int i = nodes.length - 1; i >= 0; --i) {
+      nodes[i] = visitExpression(nodes[i]);
     }
+  }
+
+  Expression visitInvokeStatic(InvokeStatic node) {
+    _rewriteList(node.arguments);
     return node;
   }
 
   Expression visitInvokeMethod(InvokeMethod node) {
-    for (int i = node.arguments.length - 1; i >= 0; --i) {
-      node.arguments[i] = visitExpression(node.arguments[i]);
-    }
+    _rewriteList(node.arguments);
     node.receiver = visitExpression(node.receiver);
     return node;
   }
 
   Expression visitInvokeMethodDirectly(InvokeMethodDirectly node) {
-    for (int i = node.arguments.length - 1; i >= 0; --i) {
-      node.arguments[i] = visitExpression(node.arguments[i]);
-    }
+    _rewriteList(node.arguments);
     node.receiver = visitExpression(node.receiver);
     return node;
   }
 
   Expression visitInvokeConstructor(InvokeConstructor node) {
-    for (int i = node.arguments.length - 1; i >= 0; --i) {
-      node.arguments[i] = visitExpression(node.arguments[i]);
-    }
+    _rewriteList(node.arguments);
     return node;
   }
 
   Expression visitConcatenateStrings(ConcatenateStrings node) {
-    for (int i = node.arguments.length - 1; i >= 0; --i) {
-      node.arguments[i] = visitExpression(node.arguments[i]);
-    }
+    _rewriteList(node.arguments);
     return node;
   }
 
@@ -561,10 +558,7 @@
   }
 
   Expression visitLiteralList(LiteralList node) {
-    // Process values right-to-left, the opposite of evaluation order.
-    for (int i = node.values.length - 1; i >= 0; --i) {
-      node.values[i] = visitExpression(node.values[i]);
-    }
+    _rewriteList(node.values);
     return node;
   }
 
@@ -578,7 +572,8 @@
   }
 
   Expression visitTypeOperator(TypeOperator node) {
-    node.receiver = visitExpression(node.receiver);
+    _rewriteList(node.typeArguments);
+    node.value = visitExpression(node.value);
     return node;
   }
 
@@ -607,9 +602,7 @@
   }
 
   Expression visitCreateInstance(CreateInstance node) {
-    for (int i = node.arguments.length - 1; i >= 0; --i) {
-      node.arguments[i] = visitExpression(node.arguments[i]);
-    }
+    _rewriteList(node.arguments);
     return node;
   }
 
@@ -624,16 +617,12 @@
   }
 
   Expression visitTypeExpression(TypeExpression node) {
-    for (int i = node.arguments.length - 1; i >= 0; --i) {
-      node.arguments[i] = visitExpression(node.arguments[i]);
-    }
+    _rewriteList(node.arguments);
     return node;
   }
 
   Expression visitCreateInvocationMirror(CreateInvocationMirror node) {
-    for (int i = node.arguments.length - 1; i >= 0; --i) {
-      node.arguments[i] = visitExpression(node.arguments[i]);
-    }
+    _rewriteList(node.arguments);
     return node;
   }
 
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart b/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
index fb69832..79bf831 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
@@ -6,7 +6,6 @@
 
 import 'optimization.dart' show Pass;
 import '../tree_ir_nodes.dart';
-import '../../elements/elements.dart' show Local, ParameterElement;
 
 /// Merges variables based on liveness and source variable information.
 ///
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
index 5b5f168..980aefb 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -82,7 +82,6 @@
   Variable phiTempVar;
 
   Variable addMutableVariable(cps_ir.MutableVariable irVariable) {
-    assert(irVariable.host == currentElement);
     assert(!mutable2variable.containsKey(irVariable));
     Variable variable = new Variable(currentElement, irVariable.hint);
     mutable2variable[irVariable] = variable;
@@ -90,7 +89,7 @@
   }
 
   Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) {
-    if (mutableVariable.host != currentElement) {
+    if (!mutable2variable.containsKey(mutableVariable)) {
       return parent.getMutableVariable(mutableVariable)..isCaptured = true;
     }
     return mutable2variable[mutableVariable];
@@ -512,9 +511,11 @@
   }
 
   Statement visitTypeOperator(cps_ir.TypeOperator node) {
-    Expression receiver = getVariableUse(node.receiver);
+    Expression value = getVariableUse(node.value);
+    List<Expression> typeArgs = translateArguments(node.typeArguments);
     Expression concat =
-        new TypeOperator(receiver, node.type, isTypeTest: node.isTypeTest);
+        new TypeOperator(value, node.type, typeArgs,
+                         isTypeTest: node.isTypeTest);
     return continueWithExpression(node.continuation, concat);
   }
 
@@ -667,6 +668,13 @@
     return new GetStatic(node.element, node.sourceInformation);
   }
 
+  Statement visitGetLazyStatic(cps_ir.GetLazyStatic node) {
+    // In the tree IR, GetStatic handles lazy fields because tree
+    // expressions are allowed to have side effects.
+    GetStatic value = new GetStatic(node.element, node.sourceInformation);
+    return continueWithExpression(node.continuation, value);
+  }
+
   Statement visitSetStatic(cps_ir.SetStatic node) {
     SetStatic setStatic = new SetStatic(
         node.element,
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
index 109dc42..fe216b1 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -331,11 +331,13 @@
 }
 
 class TypeOperator extends Expression {
-  Expression receiver;
+  Expression value;
   final DartType type;
+  final List<Expression> typeArguments;
   final bool isTypeTest;
 
-  TypeOperator(this.receiver, this.type, {bool this.isTypeTest});
+  TypeOperator(this.value, this.type, this.typeArguments,
+               {bool this.isTypeTest});
 
   accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this);
   accept1(ExpressionVisitor1 visitor, arg) {
@@ -391,9 +393,7 @@
 class FunctionExpression extends Expression implements DartSpecificNode {
   final FunctionDefinition definition;
 
-  FunctionExpression(this.definition) {
-    assert(definition.element.type.returnType.treatAsDynamic);
-  }
+  FunctionExpression(this.definition);
 
   accept(ExpressionVisitor visitor) => visitor.visitFunctionExpression(this);
   accept1(ExpressionVisitor1 visitor, arg) {
@@ -706,7 +706,7 @@
 }
 
 class FunctionDefinition extends RootNode {
-  final FunctionElement element;
+  final ExecutableElement element;
   final List<Variable> parameters;
   Statement body;
   final List<ConstDeclaration> localConstants;
@@ -873,6 +873,8 @@
   accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetField(this, arg);
 }
 
+/// Read the value of a field, possibly provoking its initializer to evaluate,
+/// or tear off a static method.
 class GetStatic extends Expression {
   Element element;
   SourceInformation sourceInformation;
@@ -883,7 +885,6 @@
   accept1(ExpressionVisitor1 visitor, arg) => visitor.visitGetStatic(this, arg);
 }
 
-
 class SetStatic extends Expression {
   Element element;
   Expression value;
@@ -1157,7 +1158,8 @@
   }
 
   visitTypeOperator(TypeOperator node) {
-    visitExpression(node.receiver);
+    visitExpression(node.value);
+    node.typeArguments.forEach(visitExpression);
   }
 
   visitFunctionExpression(FunctionExpression node) {
@@ -1349,7 +1351,8 @@
   }
 
   visitTypeOperator(TypeOperator node) {
-    node.receiver = visitExpression(node.receiver);
+    node.value = visitExpression(node.value);
+    _replaceExpressions(node.typeArguments);
     return node;
   }
 
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
index 50b4b89..e9e8865 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
@@ -456,9 +456,9 @@
   }
 
   String visitTypeOperator(TypeOperator node) {
-    String receiver = visitExpression(node.receiver);
+    String value = visitExpression(node.value);
     String type = "${node.type}";
-    return "TypeOperator $receiver ${node.operator} $type";
+    return "TypeOperator $value ${node.operator} $type";
   }
 
   String visitNot(Not node) {
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
index 82d8291..71686c9a 100644
--- a/pkg/compiler/lib/src/typechecker.dart
+++ b/pkg/compiler/lib/src/typechecker.dart
@@ -594,7 +594,6 @@
   DartType visitFunctionExpression(FunctionExpression node) {
     DartType type;
     DartType returnType;
-    DartType previousType;
     final FunctionElement element = elements.getFunctionDefinition(node);
     assert(invariant(node, element != null,
                      message: 'FunctionExpression with no element'));
@@ -994,7 +993,6 @@
       if (receiverType.treatAsDynamic || receiverType.isVoid) {
         return const DynamicAccess();
       }
-      TypeKind receiverKind = receiverType.kind;
       return lookupMember(node, receiverType, name, memberKind,
           elements[node.receiver],
           lookupClassMember: lookupClassMember ||
@@ -1239,6 +1237,10 @@
         return boolType;
       } else if (identical(name, '?')) {
         return boolType;
+      } else if (identical(name, '??')) {
+        final Node argument = node.arguments.head;
+        final DartType argumentType = analyze(argument);
+        return types.computeLeastUpperBound(receiverType, argumentType);
       }
       String operatorName = selector.source;
       if (identical(name, '-') && node.arguments.isEmpty) {
@@ -1407,7 +1409,7 @@
     Element element = elements[node];
     Identifier selector = node.selector;
     final name = node.assignmentOperator.source;
-    if (identical(name, '=')) {
+    if (identical(name, '=') || identical(name, '??=')) {
       // e1 = value
       if (node.isIndex) {
          // base[key] = value
@@ -1418,14 +1420,16 @@
         final DartType value = analyze(valueNode);
         DartType indexSet = lookupMemberType(
             node, base, '[]=', MemberKind.OPERATOR);
+        DartType indexSetValue = const DynamicType();
         if (indexSet is FunctionType) {
           FunctionType indexSetType = indexSet;
           DartType indexSetKey = firstType(indexSetType.parameterTypes);
           checkAssignable(keyNode, key, indexSetKey);
-          DartType indexSetValue = secondType(indexSetType.parameterTypes);
+          indexSetValue = secondType(indexSetType.parameterTypes);
           checkAssignable(node.assignmentOperator, value, indexSetValue);
         }
-        return value;
+        return identical(name, '=') ? value
+            : types.computeLeastUpperBound(value, indexSetValue);
       } else {
         // target = value
         DartType target;
@@ -1443,7 +1447,8 @@
         final Node valueNode = node.arguments.head;
         final DartType value = analyze(valueNode);
         checkAssignable(node.assignmentOperator, value, target);
-        return value;
+        return identical(name, '=') ? value
+            : types.computeLeastUpperBound(value, target);
       }
     } else if (identical(name, '++') || identical(name, '--')) {
       // e++ or e--
@@ -1610,7 +1615,8 @@
           checkAssignable(expression, expressionType, expectedReturnType);
         }
       }
-
+    } else if (currentAsyncMarker == AsyncMarker.ASYNC) {
+      // `return;` is allowed.
     } else if (!types.isAssignable(expectedReturnType, const VoidType())) {
       // Let f be the function immediately enclosing a return statement of the
       // form 'return;' It is a static warning if both of the following
@@ -1683,7 +1689,6 @@
   DartType visitWhile(While node) {
     checkCondition(node.condition);
     analyze(node.body);
-    Expression cond = node.condition.asParenthesizedExpression().expression;
     return const StatementType();
   }
 
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index bd52426..2fa32ef 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -480,7 +480,7 @@
                              Selector selector) {
     // Use the [:implementation] of [cls] in case the found [element]
     // is in the patch class.
-    return cls.implementation.lookupSelector(selector);
+    return cls.implementation.lookupByName(selector.memberName);
   }
 
   /**
diff --git a/pkg/compiler/lib/src/universe/side_effects.dart b/pkg/compiler/lib/src/universe/side_effects.dart
index 6b35429..66b4aa7 100644
--- a/pkg/compiler/lib/src/universe/side_effects.dart
+++ b/pkg/compiler/lib/src/universe/side_effects.dart
@@ -39,7 +39,7 @@
 
   bool _getFlag(int position) => (_flags & (1 << position)) != 0;
   void _setFlag(int position) { _flags |= (1 << position); }
-  bool _clearFlag(int position) { _flags &= ~(1 << position); }
+  void _clearFlag(int position) { _flags &= ~(1 << position); }
 
   int getChangesFlags() => _flags & ((1 << FLAG_CHANGES_COUNT) - 1);
   int getDependsOnFlags() {
diff --git a/pkg/compiler/lib/src/universe/universe.dart b/pkg/compiler/lib/src/universe/universe.dart
index c1ad13f..f5cc710 100644
--- a/pkg/compiler/lib/src/universe/universe.dart
+++ b/pkg/compiler/lib/src/universe/universe.dart
@@ -452,7 +452,8 @@
     // TODO(ngeoffray): Should the resolver do it instead?
     List<String> namedParameters;
     if (signature.optionalParametersAreNamed) {
-      namedParameters = signature.optionalParameters.mapToList((e) => e.name);
+      namedParameters =
+          signature.optionalParameters.map((e) => e.name).toList();
     }
     CallStructure callStructure =
         new CallStructure(signature.parameterCount, namedParameters);
@@ -543,11 +544,13 @@
            (memberName != INDEX_NAME && memberName != INDEX_SET_NAME));
     assert(kind == SelectorKind.OPERATOR ||
            kind == SelectorKind.INDEX ||
-           !Elements.isOperatorName(memberName.text));
+           !Elements.isOperatorName(memberName.text) ||
+           identical(memberName.text, '??'));
     assert(kind == SelectorKind.CALL ||
            kind == SelectorKind.GETTER ||
            kind == SelectorKind.SETTER ||
-           Elements.isOperatorName(memberName.text));
+           Elements.isOperatorName(memberName.text) ||
+           identical(memberName.text, '??'));
   }
 
   // TODO(johnniwinther): Extract caching.
@@ -623,7 +626,7 @@
 
   factory Selector.getterFrom(Selector selector)
       => new Selector(SelectorKind.GETTER,
-                      selector.memberName,
+                      selector.memberName.getter,
                       CallStructure.NO_ARGS);
 
   factory Selector.setter(String name, LibraryElement library)
diff --git a/pkg/compiler/lib/src/use_unused_api.dart b/pkg/compiler/lib/src/use_unused_api.dart
index 34e5f04..dd46337 100644
--- a/pkg/compiler/lib/src/use_unused_api.dart
+++ b/pkg/compiler/lib/src/use_unused_api.dart
@@ -16,7 +16,6 @@
 import 'constants/values.dart' as constants;
 import 'cps_ir/cps_ir_builder.dart' as ir_builder;
 import 'cps_ir/cps_ir_builder_task.dart' as ir_builder;
-import 'cps_ir/cps_ir_nodes_sexpr.dart' as cps_ir_nodes_sexpr;
 import 'tree_ir/tree_ir_nodes.dart' as tree_ir;
 import 'dart_types.dart' as dart_types;
 import 'dart2js.dart' as dart2js;
diff --git a/pkg/compiler/lib/src/util/link.dart b/pkg/compiler/lib/src/util/link.dart
index 648e185..b45ea6c 100644
--- a/pkg/compiler/lib/src/util/link.dart
+++ b/pkg/compiler/lib/src/util/link.dart
@@ -56,16 +56,6 @@
     return result;
   }
 
-  /// Invokes `fn` for every item in the linked list and returns the results
-  /// in a [Set].
-  Set mapToSet(dynamic fn(T item)) {
-    Set result = new Set();
-    for (Link<T> link = this; !link.isEmpty; link = link.tail) {
-      result.add(fn(link.head));
-    }
-    return result;
-  }
-
   bool get isEmpty => true;
 
   Link<T> reverse() => this;
diff --git a/pkg/compiler/lib/src/warnings.dart b/pkg/compiler/lib/src/warnings.dart
index 8977b5d..d7f1403 100644
--- a/pkg/compiler/lib/src/warnings.dart
+++ b/pkg/compiler/lib/src/warnings.dart
@@ -167,6 +167,9 @@
   static const MessageKind NO_INSTANCE_AVAILABLE = const MessageKind(
       "'#{name}' is only available in instance methods.");
 
+  static const MessageKind NO_SUPER_AVAILABLE = const MessageKind(
+      "'super' is only available in instance methods.");
+
   static const MessageKind PRIVATE_ACCESS = const MessageKind(
       "'#{name}' is declared private within library "
       "'#{libraryName}'.");
@@ -1175,6 +1178,15 @@
   static const MessageKind ASSIGNING_TYPE = const MessageKind(
       "Cannot assign a value to a type.");
 
+  static const MessageKind IF_NULL_ASSIGNING_TYPE = const MessageKind(
+      "Cannot assign a value to a type. Note that types are never null, "
+      "so this ??= assignment has no effect.",
+      howToFix: "Try removing the '??=' assignment.",
+      options: const ['--enable-null-aware-operators'],
+      examples: const [
+          "class A {} main() { print(A ??= 3);}",
+      ]);
+
   static const MessageKind VOID_NOT_ALLOWED = const MessageKind(
       "Type 'void' can't be used here because it isn't a return type.",
       howToFix: "Try removing 'void' keyword or replace it with 'var', 'final',"
@@ -1969,6 +1981,10 @@
       // This is a fall-back message that shouldn't happen.
       "Incomplete token.");
 
+  static const MessageKind NULL_AWARE_OPERATORS_DISABLED = const MessageKind(
+      "Null-aware operators like '#{operator}' are currently experimental. "
+      "You can enable them using the --enable-null-aware-operators flag.");
+
   static const MessageKind EXPONENT_MISSING = const MessageKind(
       "Numbers in exponential notation should always contain an exponent"
       " (an integer number with an optional sign).",
diff --git a/pkg/dart2js_incremental/lib/caching_compiler.dart b/pkg/dart2js_incremental/lib/caching_compiler.dart
index 7c7d341..06445cb 100644
--- a/pkg/dart2js_incremental/lib/caching_compiler.dart
+++ b/pkg/dart2js_incremental/lib/caching_compiler.dart
@@ -130,7 +130,6 @@
 
     backend.emitter.oldEmitter
         ..outputBuffers.clear()
-        ..isolateProperties = null
         ..classesCollector = null
         ..mangledFieldNames.clear()
         ..mangledGlobalFieldNames.clear()
diff --git a/pkg/js_ast/lib/src/builder.dart b/pkg/js_ast/lib/src/builder.dart
index 8603b20..12f204e 100644
--- a/pkg/js_ast/lib/src/builder.dart
+++ b/pkg/js_ast/lib/src/builder.dart
@@ -329,8 +329,6 @@
   /// [escapedString].
   LiteralString string(String value) => new LiteralString('"$value"');
 
-  LiteralString name(String name) => new LiteralString(name);
-
   LiteralNumber number(num value) => new LiteralNumber('$value');
 
   LiteralBool boolean(bool value) => new LiteralBool(value);
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index 917fcf4..57b35cf 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -1156,9 +1156,13 @@
 // separate pass because JS vars are lifted to the top of the function.
 class VarCollector extends BaseVisitor {
   bool nested;
+  bool enableRenaming = true;
   final OrderedSet<String> vars;
   final OrderedSet<String> params;
 
+  static final String disableVariableMinificationPattern = "::norenaming::";
+  static final String enableVariableMinificationPattern = "::dorenaming::";
+
   VarCollector() : nested = false,
                    vars = new OrderedSet<String>(),
                    params = new OrderedSet<String>();
@@ -1195,8 +1199,16 @@
 
   void visitThis(This node) {}
 
+  void visitComment(Comment node) {
+    if (node.comment.contains(disableVariableMinificationPattern)) {
+      enableRenaming = false;
+    } else if (node.comment.contains(enableVariableMinificationPattern)) {
+      enableRenaming = true;
+    }
+  }
+
   void visitVariableDeclaration(VariableDeclaration decl) {
-    if (decl.allowRename) vars.add(decl.name);
+    if (enableRenaming && decl.allowRename) vars.add(decl.name);
   }
 }
 
diff --git a/pkg/js_ast/lib/src/template.dart b/pkg/js_ast/lib/src/template.dart
index eb4089a..e7aa863 100644
--- a/pkg/js_ast/lib/src/template.dart
+++ b/pkg/js_ast/lib/src/template.dart
@@ -56,6 +56,7 @@
 
   Template(this.source, this.ast,
            {this.isExpression: true, this.forceCopy: false}) {
+    assert(this.isExpression ? ast is Expression : ast is Statement);
     _compile();
   }
 
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 18f2652..1889628 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -11,6 +11,9 @@
 */*/*/*/packages/*/*: Skip
 */*/*/*/*/packages/*/*: Skip
 
+# Analyzer2dart is not maintained anymore.
+analyzer2dart/test/*: Skip
+
 [ $compiler != dartanalyzer && $compiler != dart2analyzer ]
 docgen/test/inherited_comments_test: Fail # issue 22233
 
@@ -124,7 +127,6 @@
 http_server/test/*: Fail, OK # Uses dart:io.
 observe/test/transformer_test: Fail, OK # Uses dart:io.
 observe/test/unique_message_test: SkipByDesign  # Uses dart:io.
-stub_core_library/test/*: Fail, OK # Uses dart:io.
 
 [ $runtime == vm && ($arch == simarm64 || $arch == simarm || $arch == simarmv5te || $arch == simmips || $arch == armv5te) ]
 # Timeout. These are not unit tests. They do not run efficiently on our
@@ -142,7 +144,7 @@
 analyzer/test/*: PubGetError
 
 [ $compiler == dart2js && $cps_ir ]
-analysis_server/tool/spec/check_all_test: Crash # unsupported element kind: context:field
+analysis_server/tool/spec/check_all_test: Crash #  Unhandled node
 analyzer/test/cancelable_future_test: Crash #  try/finally
 analyzer/test/enum_test: Crash #  try/finally
 analyzer/test/file_system/memory_file_system_test: Crash #  try/finally
@@ -164,7 +166,7 @@
 analyzer/test/generated/static_warning_code_test: Crash #  try/finally
 analyzer/test/generated/utilities_test: Crash #  try/finally
 analyzer/test/instrumentation/instrumentation_test: Crash #  try/finally
-analyzer/test/parse_compilation_unit_test: Crash # unsupported element kind: _escapeRegExp:field
+analyzer/test/parse_compilation_unit_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 analyzer/test/source/package_map_provider_test: Crash #  try/finally
 analyzer/test/source/package_map_resolver_test: Crash #  try/finally
 analyzer/test/src/context/cache_test: Crash #  try/finally
@@ -179,15 +181,9 @@
 analyzer/test/src/task/model_test: Crash #  try/finally
 analyzer/test/src/util/asserts_test: Crash #  try/finally
 analyzer/test/src/util/lru_map_test: Crash #  try/finally
-analyzer2dart/test/driver_test: Crash # unsupported element kind: _escapeRegExp:field
-analyzer2dart/test/end2end_test: Crash # unsupported element kind: _escapeRegExp:field
-analyzer2dart/test/identifier_semantics_test: Crash # unsupported element kind: NOT_SDK:field
-analyzer2dart/test/sexpr_test: Crash # unsupported element kind: _escapeRegExp:field
-analyzer2dart/test/tree_shaker_test: Crash # unsupported element kind: _escapeRegExp:field
 fixnum/test/int_32_test: Crash #  try/finally
 fixnum/test/int_64_test: Crash #  try/finally
-js_ast/test/printer_callback_test: Crash # unsupported element kind: templateManager:field
-stub_core_library/test/stub_test: Crash #  try/finally
-typed_data/test/typed_buffers_test/01: Crash # unsupported element kind: _escapeRegExp:field
-typed_data/test/typed_buffers_test/none: Crash # unsupported element kind: _escapeRegExp:field
+js_ast/test/printer_callback_test: Crash #  Unhandled node
+typed_data/test/typed_buffers_test/01: Crash # Instance of 'TypeOperator': type casts not implemented.
+typed_data/test/typed_buffers_test/none: Crash # Instance of 'TypeOperator': type casts not implemented.
 typed_mock/test/typed_mock_test: Crash #  try/finally
diff --git a/pkg/stub_core_library/README.md b/pkg/stub_core_library/README.md
deleted file mode 100644
index acc40e6..0000000
--- a/pkg/stub_core_library/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-This package exists to create stubs for core libraries that can't be safely
-imported on some platforms: `dart:io`, `dart:html`, and so on. These stubs are
-included in the SDK and used by pub to support cross-platform packages.
-
-This is an application package and is not intended to be uploaded to
-pub.dartlang.org.
diff --git a/pkg/stub_core_library/bin/stub_core_library.dart b/pkg/stub_core_library/bin/stub_core_library.dart
deleted file mode 100644
index 9bf638c..0000000
--- a/pkg/stub_core_library/bin/stub_core_library.dart
+++ /dev/null
@@ -1,101 +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 stub_core_library.bin;
-
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:path/path.dart' as p;
-
-import 'package:stub_core_library/src/utils.dart';
-import 'package:stub_core_library/stub_core_library.dart';
-
-/// A map from Dart core library sources to the filenames into which they should
-/// be generated.
-///
-/// The source paths are URL-formatted and relative to the Dart SDK root.
-const CORE_LIBRARIES = const {
-  'lib/io/io.dart': 'dart_io.dart',
-  'lib/html/html_common/html_common.dart': 'dart_html_common.dart',
-  'lib/html/html_common/metadata.dart': 'metadata.dart',
-  'lib/html/dartium/html_dartium.dart': 'dart_html.dart',
-  'lib/indexed_db/dartium/indexed_db_dartium.dart': 'dart_indexed_db.dart',
-  'lib/js/dartium/js_dartium.dart': 'dart_js.dart',
-  'lib/svg/dartium/svg_dartium.dart': 'dart_svg.dart',
-  'lib/web_audio/dartium/web_audio_dartium.dart': 'dart_web_audio.dart',
-  'lib/web_gl/dartium/web_gl_dartium.dart': 'dart_web_gl.dart',
-  'lib/web_sql/dartium/web_sql_dartium.dart': 'dart_web_sql.dart'
-};
-
-/// A map from stubbable "dart:" URLs to the names of the stub files they should
-/// be replaced with.
-const IMPORT_REPLACEMENTS = const {
-  'dart:io': 'dart_io.dart',
-  'dart:html_common': 'dart_html_common.dart',
-  'dart:html': 'dart_html.dart',
-  'dart:indexed_db': 'dart_indexed_db.dart',
-  'dart:js': 'dart_js.dart',
-  'dart:svg': 'dart_svg.dart',
-  'dart:web_audio': 'dart_web_audio.dart',
-  'dart:web_gl': 'dart_web_gl.dart',
-  'dart:web_sql': 'dart_web_sql.dart'
-};
-
-/// The exit code for a usage error.
-const USAGE_ERROR = 64;
-
-/// The root directory of the SDK.
-String get sdkRoot => p.join(
-    p.dirname(p.fromUri(Platform.script)), '..', '..', '..', 'sdk');
-
-/// The argument parser.
-final argParser = new ArgParser()
-    ..addFlag('help', abbr: 'h', help: 'Print this usage information.');
-
-/// The usage string.
-String get usage => """
-Generate Dart core library stubs.
-
-Usage: stub_core_libraries.dart <directory>
-
-${argParser.getUsage()}""";
-
-void main(List<String> arguments) {
-  var options;
-  try {
-    options = argParser.parse(arguments);
-  } on FormatException catch (e) {
-    stderr.writeln(e.message);
-    stderr.writeln(usage);
-    exitCode = USAGE_ERROR;
-    return;
-  }
-
-  if (options['help']) {
-    print(usage);
-    return;
-  }
-
-  var destination = options.rest.isEmpty ? p.current : options.rest.first;
-
-  // Don't allow extra arguments.
-  if (options.rest.length > 1) {
-    var unexpected = options.rest.skip(1).map((arg) => '"$arg"');
-    var arguments = pluralize("argument", unexpected.length);
-    stderr.writeln("Unexpected $arguments ${toSentence(unexpected)}.");
-    stderr.writeln(usage);
-    exitCode = USAGE_ERROR;
-    return;
-  }
-
-  new Directory(destination).createSync(recursive: true);
-
-  // TODO(nweiz): Tree-shake these libraries when issue 19896 is fixed.
-  CORE_LIBRARIES.forEach((path, output) {
-    path = p.join(sdkRoot, p.fromUri(path));
-    new File(p.join(destination, output))
-        .writeAsStringSync(stubFile(path, IMPORT_REPLACEMENTS));
-  });
-}
diff --git a/pkg/stub_core_library/lib/src/utils.dart b/pkg/stub_core_library/lib/src/utils.dart
deleted file mode 100644
index d5bdd8f..0000000
--- a/pkg/stub_core_library/lib/src/utils.dart
+++ /dev/null
@@ -1,24 +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 stub_core_libraries.utils;
-
-/// Returns a sentence fragment listing the elements of [iter].
-///
-/// This converts each element of [iter] to a string and separates them with
-/// commas and/or "and" where appropriate.
-String toSentence(Iterable iter) {
-  if (iter.length == 1) return iter.first.toString();
-  return iter.take(iter.length - 1).join(", ") + " and ${iter.last}";
-}
-
-/// Returns [name] if [number] is 1, or the plural of [name] otherwise.
-///
-/// By default, this just adds "s" to the end of [name] to get the plural. If
-/// [plural] is passed, that's used instead.
-String pluralize(String name, int number, {String plural}) {
-  if (number == 1) return name;
-  if (plural != null) return plural;
-  return '${name}s';
-}
diff --git a/pkg/stub_core_library/lib/stub_core_library.dart b/pkg/stub_core_library/lib/stub_core_library.dart
deleted file mode 100644
index d61053e..0000000
--- a/pkg/stub_core_library/lib/stub_core_library.dart
+++ /dev/null
@@ -1,391 +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 stub_core_library;
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:path/path.dart' as p;
-
-/// Returns the contents of a stub version of the library at [path].
-///
-/// A stub library has the same API as the original library, but none of the
-/// implementation. Specifically, this guarantees that any code that worked with
-/// the original library will be statically valid with the stubbed library, and
-/// its only runtime errors will be [UnsupportedError]s. This means that
-/// constants and const constructors are preserved.
-///
-/// [importReplacements] is a map from import URIs to their replacements. It's
-/// used so that mutliple interrelated libraries can refer to their stubbed
-/// versions rather than the originals.
-String stubFile(String path, [Map<String, String> importReplacements]) {
-  var visitor = new _StubVisitor(path, importReplacements);
-  parseDartFile(path).accept(visitor);
-  return visitor.toString();
-}
-
-/// Returns the contents of a stub version of the library parsed from [code].
-///
-/// If [code] contains `part` directives, they will be resolved relative to
-/// [path]. The contents of the parted files will be stubbed and inlined.
-String stubCode(String code, String path,
-    [Map<String, String> importReplacements]) {
-  var visitor = new _StubVisitor(path, importReplacements);
-  parseCompilationUnit(code, name: path).accept(visitor);
-  return visitor.toString();
-}
-
-/// An AST visitor that traverses the tree of the original library and writes
-/// the stubbed version.
-///
-/// In order to avoid complex tree-shaking logic, this takes a conservative
-/// approach to removing private code. Private classes may still be extended by
-/// public classes; private constants may be referenced by public constants; and
-/// private static and top-level methods may be referenced by public constants
-/// or by superclass constructor calls. All of these are preserved even though
-/// most could theoretically be eliminated.
-class _StubVisitor extends ToSourceVisitor {
-  /// The directory containing the library being visited.
-  final String _root;
-
-  /// Which imports to replace.
-  final Map<String, String> _importReplacements;
-
-  final PrintStringWriter _writer;
-
-  // TODO(nweiz): Get rid of this when issue 19897 is fixed.
-  /// The current class declaration being visited.
-  ///
-  /// This is `null` if there is no current class declaration.
-  ClassDeclaration _class;
-
-  _StubVisitor(String path, Map<String, String> importReplacements)
-      : this._(path, importReplacements, new PrintStringWriter());
-
-  _StubVisitor._(String path, Map<String, String> importReplacements,
-          PrintStringWriter writer)
-      : _root = p.dirname(path),
-        _importReplacements = importReplacements == null ? const {} :
-            importReplacements,
-        _writer = writer,
-        super(writer);
-
-  String toString() => _writer.toString();
-
-  visitImportDirective(ImportDirective node) {
-    node = _modifyDirective(node);
-    if (node != null) super.visitImportDirective(node);
-  }
-
-  visitExportDirective(ExportDirective node) {
-    node = _modifyDirective(node);
-    if (node != null) super.visitExportDirective(node);
-  }
-
-  visitPartDirective(PartDirective node) {
-    // Inline parts directly in the output file.
-    var path = p.url.join(_root, p.fromUri(node.uri.stringValue));
-    parseDartFile(path).accept(new _StubVisitor._(path, const {}, _writer));
-  }
-
-  visitPartOfDirective(PartOfDirective node) {
-    // Remove "part of", since parts are inlined.
-  }
-
-  visitClassDeclaration(ClassDeclaration node) {
-    _class = _clone(node);
-    _class.nativeClause = null;
-    super.visitClassDeclaration(_class);
-    _class = null;
-  }
-
-  visitConstructorDeclaration(ConstructorDeclaration node) {
-    node = _withoutExternal(node);
-
-    // Remove field initializers and redirecting initializers but not superclass
-    // initializers. The code is ugly because NodeList doesn't support
-    // removeWhere.
-    var superclassInitializers = node.initializers.where((initializer) =>
-        initializer is SuperConstructorInvocation).toList();
-    node.initializers.clear();
-    node.initializers.addAll(superclassInitializers);
-
-    // Add a space because ToSourceVisitor doesn't and it makes testing easier.
-    _writer.print(" ");
-    super.visitConstructorDeclaration(node);
-  }
-
-  visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    // If this is a const constructor, it should actually work, so don't screw
-    // with the superclass constructor.
-    if ((node.parent as ConstructorDeclaration).constKeyword != null) {
-      return super.visitSuperConstructorInvocation(node);
-    }
-
-    _writer.print("super");
-    _visitNodeWithPrefix(".", node.constructorName);
-    _writer.print("(");
-
-    // If one stubbed class extends another, we don't want to run the original
-    // code for the superclass constructor call, and we do want an
-    // UnsupportedException that points to the subclass rather than the
-    // superclass. To do this, we null out all but the first superclass
-    // constructor parameter and replace the first parameter with a throw.
-    var positionalArguments = node.argumentList.arguments
-        .where((argument) => argument is! NamedExpression);
-    if (positionalArguments.isNotEmpty) {
-      _writer.print(_unsupported(_functionName(node)));
-      for (var i = 0; i < positionalArguments.length - 1; i++) {
-        _writer.print(", null");
-      }
-    }
-
-    _writer.print(")");
-  }
-
-  visitMethodDeclaration(MethodDeclaration node) {
-    // Private non-static methods aren't public and aren't accessible from
-    // constant expressions, so can be safely removed.
-    if (Identifier.isPrivateName(node.name.name) && !node.isStatic) return;
-    _writer.print(" ");
-    super.visitMethodDeclaration(_withoutExternal(node));
-  }
-
-  visitFunctionDeclaration(FunctionDeclaration node) {
-    super.visitFunctionDeclaration(_withoutExternal(node));
-  }
-
-  visitBlockFunctionBody(BlockFunctionBody node) => _emitFunctionBody(node);
-
-  visitExpressionFunctionBody(ExpressionFunctionBody node) =>
-      _emitFunctionBody(node);
-
-  visitNativeFunctionBody(NativeFunctionBody node) => _emitFunctionBody(node);
-
-  visitEmptyFunctionBody(FunctionBody node) {
-    // Preserve empty function bodies for abstract methods, since there's no
-    // reason not to. Note that "empty" here means "foo();" not "foo() {}".
-    var isAbstractMethod = node.parent is MethodDeclaration &&
-        !(node.parent as MethodDeclaration).isStatic && _class != null &&
-        _class.isAbstract;
-
-    // Preserve empty function bodies for const constructors because we want
-    // them to continue to work.
-    var isConstConstructor = node.parent is ConstructorDeclaration &&
-        (node.parent as ConstructorDeclaration).constKeyword != null;
-
-    if (isAbstractMethod || isConstConstructor) {
-      super.visitEmptyFunctionBody(node);
-      _writer.print(" ");
-    } else {
-      _writer.print(" ");
-      _emitFunctionBody(node);
-    }
-  }
-
-  visitFieldFormalParameter(FieldFormalParameter node) {
-    // Remove "this." because instance variables are replaced with getters and
-    // setters or just set to null.
-    _emitTokenWithSuffix(node.keyword, " ");
-
-    // Make sure the parameter is still typed by grabbing the type from the
-    // associated instance variable.
-    var type = node.type;
-    if (type == null) {
-      var variable = _class.members
-          .where((member) => member is FieldDeclaration)
-          .expand((member) => member.fields.variables)
-          .firstWhere((variable) => variable.name.name == node.identifier.name,
-              orElse: () => null);
-      if (variable != null) type = variable.parent.type;
-    }
-
-    _visitNodeWithSuffix(type, " ");
-    _visitNode(node.identifier);
-    _visitNode(node.parameters);
-  }
-
-  visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    node.variables.variables.forEach(_emitVariableDeclaration);
-  }
-
-  visitFieldDeclaration(FieldDeclaration node) {
-    _writer.print(" ");
-    node.fields.variables.forEach(_emitVariableDeclaration);
-  }
-
-  /// Modifies a directive to respect [importReplacements] and ignore hidden
-  /// core libraries.
-  ///
-  /// This can return `null`, indicating that the directive should not be
-  /// emitted.
-  UriBasedDirective _modifyDirective(UriBasedDirective node) {
-    // Ignore internal "dart:" libraries.
-    if (node.uri.stringValue.startsWith('dart:_')) return null;
-
-    // Replace libraries in [importReplacements].
-    if (_importReplacements.containsKey(node.uri.stringValue)) {
-      node = _clone(node);
-      var token = new StringToken(TokenType.STRING,
-          '"${_importReplacements[node.uri.stringValue]}"', 0);
-      node.uri = new SimpleStringLiteral(token, null);
-    }
-
-    return node;
-  }
-
-  /// Emits a variable declaration, either as a literal variable or as a getter
-  /// and maybe a setter that throw [UnsupportedError]s.
-  _emitVariableDeclaration(VariableDeclaration node) {
-    VariableDeclarationList parent = node.parent;
-    var isStatic = node.parent.parent is FieldDeclaration &&
-        (node.parent.parent as FieldDeclaration).isStatic;
-
-    // Preserve constants as-is.
-    if (node.isConst) {
-      if (isStatic) _writer.print("static ");
-      _writer.print("const ");
-      _visitNode(node);
-      _writer.print("; ");
-      return;
-    }
-
-    // Ignore non-const private variables.
-    if (Identifier.isPrivateName(node.name.name)) return;
-
-    // There's no need to throw errors for instance fields of classes that can't
-    // be constructed.
-    if (!isStatic && _class != null && !_inConstructableClass) {
-      _emitTokenWithSuffix(parent.keyword, " ");
-      _visitNodeWithSuffix(parent.type, " ");
-      _visitNode(node.name);
-      // Add an initializer to make sure that final variables are initialized.
-      if (node.isFinal) _writer.print(" = null; ");
-      return;
-    }
-
-    var name = node.name.name;
-    if (_class != null) name = "${_class.name}.$name";
-
-    // Convert public variables into getters and setters that throw
-    // UnsupportedErrors.
-    if (isStatic) _writer.print("static ");
-    _visitNodeWithSuffix(parent.type, " ");
-    _writer.print("get ");
-    _visitNode(node.name);
-    _writer.print(" => ${_unsupported(name)}; ");
-    if (node.isFinal) return;
-
-    if (isStatic) _writer.print("static ");
-    _writer.print("set ");
-    _visitNode(node.name);
-    _writer.print("(");
-    _visitNodeWithSuffix(parent.type, " ");
-    _writer.print("_) { ${_unsupported("$name=")}; } ");
-  }
-
-  /// Emits a function body.
-  ///
-  /// This usually emits a body that throws an [UnsupportedError], but it can
-  /// emit an empty body as well.
-  void _emitFunctionBody(FunctionBody node) {
-    // There's no need to throw errors for instance methods of classes that
-    // can't be constructed.
-    var parent = node.parent;
-    if (parent is MethodDeclaration && !parent.isStatic &&
-        !_inConstructableClass) {
-      _writer.print('{} ');
-      return;
-    }
-
-    _writer.print('{ ${_unsupported(_functionName(node))}; } ');
-  }
-
-  // Returns a human-readable name for the function containing [node].
-  String _functionName(AstNode node) {
-    // Come up with a nice name for the error message so users can tell exactly
-    // what unsupported method they're calling.
-    var function = node.getAncestor((ancestor) =>
-        ancestor is FunctionDeclaration || ancestor is MethodDeclaration);
-    if (function != null) {
-      var name = function.name.name;
-      if (function.isSetter) {
-        name = "$name=";
-      } else if (!function.isGetter &&
-          !(function is MethodDeclaration && function.isOperator)) {
-        name = "$name()";
-      }
-      if (_class != null) name = "${_class.name}.$name";
-      return name;
-    }
-
-    var constructor = node.getAncestor((ancestor) =>
-        ancestor is ConstructorDeclaration);
-    if (constructor == null) return "This function";
-
-    var name = "new ${constructor.returnType.name}";
-    if (constructor.name != null) name = "$name.${constructor.name}";
-    return "$name()";
-  }
-
-  /// Returns a deep copy of [node].
-  AstNode _clone(AstNode node) => node.accept(new AstCloner());
-
-  /// Returns a deep copy of [node] without the "external" keyword.
-  AstNode _withoutExternal(node) {
-    var clone = node.accept(new AstCloner());
-    clone.externalKeyword = null;
-    return clone;
-  }
-
-  /// Visits [node] if it's non-`null`.
-  void _visitNode(AstNode node) {
-    if (node != null) node.accept(this);
-  }
-
-  /// Visits [node] then emits [suffix] if [node] isn't `null`.
-  void _visitNodeWithSuffix(AstNode node, String suffix) {
-    if (node == null) return;
-    node.accept(this);
-    _writer.print(suffix);
-  }
-
-  /// Emits [prefix] then visits [node] if [node] isn't `null`.
-  void _visitNodeWithPrefix(String prefix, AstNode node) {
-    if (node == null) return;
-    _writer.print(prefix);
-    node.accept(this);
-  }
-
-  /// Emits [token] followed by [suffix] if [token] isn't `null`.
-  void _emitTokenWithSuffix(Token token, String suffix) {
-    if (token == null) return;
-    _writer.print(token.lexeme);
-    _writer.print(suffix);
-  }
-
-  /// Returns an expression that throws an [UnsupportedError] explaining that
-  /// [name] isn't supported.
-  String _unsupported(String name) => 'throw new UnsupportedError("$name is '
-      'unsupported on this platform.")';
-
-  /// Returns whether or not the visitor is currently visiting a class that can
-  /// be constructed without error after it's stubbed.
-  ///
-  /// There are two cases where a class will be constructable once it's been
-  /// stubbed. First, a class with a const constructor will be preserved, since
-  /// making the const constructor fail would statically break code. Second, a
-  /// class with a default constructor is preserved since adding a constructor
-  /// that throws an error could statically break uses of the class as a mixin.
-  bool get _inConstructableClass {
-    if (_class == null) return false;
-
-    var constructors = _class.members.where((member) =>
-        member is ConstructorDeclaration);
-    if (constructors.isEmpty) return true;
-
-    return constructors.any((constructor) => constructor.constKeyword != null);
-  }
-}
diff --git a/pkg/stub_core_library/pubspec.yaml b/pkg/stub_core_library/pubspec.yaml
deleted file mode 100644
index 767b950..0000000
--- a/pkg/stub_core_library/pubspec.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: stub_core_library
-description: A repo-internal package for creating core library stubs.
-dependencies:
-  args: ">=0.11.0 <0.14.0"
-  analyzer: ">=0.22.0-dev <0.23.0"
-  path: ">=1.1.0 <2.0.0"
diff --git a/pkg/stub_core_library/test/stub_test.dart b/pkg/stub_core_library/test/stub_test.dart
deleted file mode 100644
index 5cdb775..0000000
--- a/pkg/stub_core_library/test/stub_test.dart
+++ /dev/null
@@ -1,428 +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 stub_core_libraries.test;
-
-import 'dart:io';
-
-import 'package:path/path.dart' as p;
-import 'package:stub_core_library/stub_core_library.dart';
-import 'package:unittest/unittest.dart';
-
-String sandbox;
-
-main() {
-  setUp(() {
-    sandbox = Directory.systemTemp.createTempSync('stub_core_library_').path;
-  });
-
-  tearDown(() => new Directory(sandbox).deleteSync(recursive: true));
-
-  group("imports", () {
-    test("dart: imports are preserved by default", () {
-      expectStub("""
-        import "dart:core";
-        import "dart:html";
-        import "dart:fblthp";
-      """, """
-        import "dart:core";
-        import "dart:html";
-        import "dart:fblthp";
-      """);
-    });
-
-    test("internal dart: imports are removed", () {
-      expectStub("""
-        import "dart:_internal";
-        import "dart:_blink" as _blink;
-        import "dart:_fblthp";
-      """, "");
-    });
-
-    test("replaced imports are replaced", () {
-      expectStub("""
-        import "dart:html";
-        import "foo.dart" as foo;
-      """, """
-        import "dart_html.dart";
-        import "bar.dart" as foo;
-      """, {
-        "dart:html": "dart_html.dart",
-        "foo.dart": "bar.dart"
-      });
-    });
-
-    test("exports are replaced as well", () {
-      expectStub("""
-        export "dart:html";
-        export "foo.dart" show foo;
-      """, """
-        export "dart_html.dart";
-        export "bar.dart" show foo;
-      """, {
-        "dart:html": "dart_html.dart",
-        "foo.dart": "bar.dart"
-      });
-    });
-  });
-
-  test("a parted file is stubbed and included inline", () {
-    new File(p.join(sandbox, "part.dart")).writeAsStringSync("""
-      part of lib;
-      void foo() => print('foo!');
-    """);
-
-    expectStub("""
-      library lib;
-      part "part.dart";
-    """, """
-      library lib;
-      void foo() { ${unsupported("foo()")}; }
-    """);
-  });
-
-  test("a class declaration's native clause is removed", () {
-    expectStub("class Foo native 'Foo' {}", "class Foo {}");
-  });
-
-  group("constructors", () {
-    test("a constructor's body is stubbed out", () {
-      expectStub("""
-        class Foo {
-          Foo() { print("Created a foo!"); }
-        }
-      """, """
-        class Foo {
-          Foo() { ${unsupported("new Foo()")}; }
-        }
-      """);
-    });
-
-    test("a constructor's empty body is stubbed out", () {
-      expectStub("class Foo { Foo(); }", """
-        class Foo {
-          Foo() { ${unsupported("new Foo()")}; }
-        }
-      """);
-    });
-
-    test("a constructor's external declaration is removed", () {
-      expectStub("class Foo { external Foo(); }", """
-        class Foo {
-          Foo() { ${unsupported("new Foo()")}; }
-        }
-      """);
-    });
-
-    test("a constructor's field initializers are removed", () {
-      expectStub("""
-        class Foo {
-          final _field1;
-          final _field2;
-
-          Foo()
-            : _field1 = 1,
-              _field2 = 2;
-        }
-      """, """
-        class Foo {
-          Foo() { ${unsupported("new Foo()")}; }
-        }
-      """);
-    });
-
-    test("a constructor's redirecting initializers are removed", () {
-      expectStub("""
-        class Foo {
-          Foo() : this.create();
-          Foo.create();
-        }
-      """, """
-        class Foo {
-          Foo() { ${unsupported("new Foo()")}; }
-          Foo.create() { ${unsupported("new Foo.create()")}; }
-        }
-      """);
-    });
-
-    test("a constructor's superclass calls are preserved", () {
-      expectStub("""
-        class Foo {
-          Foo(int i, int j, {int k});
-        }
-
-        class Bar extends Foo {
-          Bar() : super(1, 2, k: 3);
-        }
-      """, """
-        class Foo {
-          Foo(int i, int j, {int k}) { ${unsupported("new Foo()")}; }
-        }
-
-        class Bar extends Foo {
-          Bar()
-              : super(${unsupported("new Bar()")}, null) {
-            ${unsupported("new Bar()")};
-          }
-        }
-      """);
-    });
-
-    test("a constructor's initializing formals are replaced with normal "
-        "parameters", () {
-      expectStub("""
-        class Foo {
-          final int _i;
-          var _j;
-          final List<int> _k;
-
-          Foo(this._i, this._j, this._k);
-        }
-      """, """
-        class Foo {
-          Foo(int _i, _j, List<int> _k) { ${unsupported("new Foo()")}; }
-        }
-      """);
-    });
-
-    test("a const constructor isn't stubbed", () {
-      expectStub("class Foo { const Foo(); }", "class Foo { const Foo(); }");
-    });
-
-    test("a const constructor's superclass calls are fully preserved", () {
-      expectStub("""
-        class Foo {
-          const Foo(int i, int j, int k);
-        }
-
-        class Bar extends Foo {
-          const Bar() : super(1, 2, 3);
-        }
-      """, """
-        class Foo {
-          const Foo(int i, int j, int k);
-        }
-
-        class Bar extends Foo {
-          const Bar() : super(1, 2, 3);
-        }
-      """);
-    });
-
-    test("a redirecting const constructor stops redirecting", () {
-      expectStub("""
-        class Foo {
-          const Foo.named(int i, int j, int k)
-              : this(i, j, k);
-          const Foo(int i, int j, int k);
-        }
-      """, """
-        class Foo {
-          const Foo.named(int i, int j, int k);
-          const Foo(int i, int j, int k);
-        }
-      """);
-    });
-  });
-
-  group("functions", () {
-    test("stubs a top-level function", () {
-      expectStub("void foo() => print('hello!');",
-          "void foo() { ${unsupported('foo()')}; }");
-    });
-
-    test("stubs a private top-level function", () {
-      expectStub("void _foo() => print('hello!');",
-          "void _foo() { ${unsupported('_foo()')}; }");
-    });
-
-    test("stubs a method", () {
-      expectStub("""
-        class Foo {
-          foo() => print("hello!");
-        }
-      """, """
-        class Foo {
-          foo() { ${unsupported('Foo.foo()')}; }
-        }
-      """);
-    });
-
-    test("empties a method in an unconstructable class", () {
-      expectStub("""
-        class Foo {
-          Foo();
-          foo() => print("hello!");
-        }
-      """, """
-        class Foo {
-          Foo() { ${unsupported('new Foo()')}; }
-          foo() {}
-        }
-      """);
-    });
-
-    test("removes a private instance method", () {
-      expectStub("""
-        class Foo {
-          _foo() => print("hello!");
-        }
-      """, "class Foo {}");
-    });
-
-    test("stubs a private static method", () {
-      expectStub("""
-        class Foo {
-          static _foo() => print("hello!");
-        }
-      """, """
-        class Foo {
-          static _foo() { ${unsupported('Foo._foo()')}; }
-        }
-      """);
-    });
-
-    test("preserves an abstract instance method", () {
-      expectStub("abstract class Foo { foo(); }",
-          "abstract class Foo { foo(); }");
-    });
-
-    test("removes a native function body", () {
-      expectStub("void foo() native 'foo';",
-          "void foo() { ${unsupported('foo()')}; }");
-    });
-  });
-
-  group("top-level fields", () {
-    test("stubs out a top-level field", () {
-      expectStub("int foo;", """
-        int get foo => ${unsupported('foo')};
-        set foo(int _) { ${unsupported('foo=')}; }
-      """);
-    });
-
-    test("stubs out a top-level field with a value", () {
-      expectStub("int foo = 12;", """
-        int get foo => ${unsupported('foo')};
-        set foo(int _) { ${unsupported('foo=')}; }
-      """);
-    });
-
-    test("stubs out a final top-level field", () {
-      expectStub("final int foo = 12;",
-          "int get foo => ${unsupported('foo')};");
-    });
-
-    test("preserves a const top-level field", () {
-      expectStub("const foo = 12;", "const foo = 12;");
-    });
-
-    test("removes a private top-level field", () {
-      expectStub("int _foo = 12;", "");
-    });
-
-    test("preserves a private const top-level field", () {
-      expectStub("const _foo = 12;", "const _foo = 12;");
-    });
-
-    test("splits a multiple-declaration top-level field", () {
-      expectStub("int foo, bar, baz;", """
-        int get foo => ${unsupported('foo')};
-        set foo(int _) { ${unsupported('foo=')}; }
-        int get bar => ${unsupported('bar')};
-        set bar(int _) { ${unsupported('bar=')}; }
-        int get baz => ${unsupported('baz')};
-        set baz(int _) { ${unsupported('baz=')}; }
-      """);
-    });
-  });
-
-  group("instance fields", () {
-    test("stubs out an instance field", () {
-      expectStub("class Foo { int foo; }", """
-        class Foo {
-          int get foo => ${unsupported('Foo.foo')};
-          set foo(int _) { ${unsupported('Foo.foo=')}; }
-        }
-      """);
-    });
-
-    test("stubs out an instance field with a value", () {
-      expectStub("class Foo { int foo = 12; }", """
-        class Foo {
-          int get foo => ${unsupported('Foo.foo')};
-          set foo(int _) { ${unsupported('Foo.foo=')}; }
-        }
-      """);
-    });
-
-    test("stubs out a final instance field", () {
-      expectStub("class Foo { final int foo = 12; }", """
-        class Foo {
-           int get foo => ${unsupported('Foo.foo')};
-        }
-      """);
-    });
-
-    test("removes a private instance field", () {
-      expectStub("class Foo { int _foo = 12; }", "class Foo { }");
-    });
-
-    test("stubs out a static instance field", () {
-      expectStub("class Foo { static int foo = 12; }", """
-        class Foo {
-           static int get foo => ${unsupported('Foo.foo')};
-           static set foo(int _) { ${unsupported('Foo.foo=')}; }
-        }
-      """);
-    });
-
-    test("removes a private static instance field", () {
-      expectStub("class Foo { static int _foo = 12; }", "class Foo { }");
-    });
-
-    test("preserves a static const instance field", () {
-      expectStub("class Foo { static const foo = 12; }",
-          "class Foo { static const foo = 12; }");
-    });
-
-    test("nulls a field for an unconstructable class", () {
-      expectStub("""
-        class Foo {
-          Foo();
-          final foo = 12;
-        }
-      """, """
-        class Foo {
-          Foo() { ${unsupported("new Foo()")}; }
-          final foo = null;
-        }
-      """);
-    });
-
-    test("splits a multiple-declaration instance field", () {
-      expectStub("class Foo { int foo, bar, baz; }", """
-        class Foo {
-          int get foo => ${unsupported('Foo.foo')};
-          set foo(int _) { ${unsupported('Foo.foo=')}; }
-          int get bar => ${unsupported('Foo.bar')};
-          set bar(int _) { ${unsupported('Foo.bar=')}; }
-          int get baz => ${unsupported('Foo.baz')};
-          set baz(int _) { ${unsupported('Foo.baz=')}; }
-        }
-      """);
-    });
-  });
-}
-
-/// Expects that [source] will transform into [expected] when stubbed.
-void expectStub(String source, String expected,
-    [Map<String, String> importReplacements]) {
-  expect(stubCode(source, p.join(sandbox, 'source.dart'), importReplacements),
-      equalsIgnoringWhitespace(expected));
-}
-
-/// Returns code for throwing an [UnsupportedError] for the given name.
-String unsupported(String name) => 'throw new UnsupportedError("$name is '
-    'unsupported on this platform.")';
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index beaf048..ad90805 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -111,7 +111,7 @@
 executable("libdart_dependency_helper") {
   configs += [":dart_config"]
   deps = [
-    "vm:libdart_lib_withcore",
+    "vm:libdart_lib_nosnapshot",
     "vm:libdart_lib",
     "vm:libdart_vm",
     "vm:libdart_platform",
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index ebb92c9..a7604ff 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -108,11 +108,11 @@
 }
 
 
-static_library("libdart_withcore") {
+static_library("libdart_nosnapshot") {
   configs += ["..:dart_config"]
   deps = [
-    "../vm:libdart_lib_withcore",
-    "../vm:libdart_vm",
+    "../vm:libdart_lib_nosnapshot",
+    "../vm:libdart_vm_nosnapshot",
     "../vm:libdart_platform",
     "../third_party/double-conversion/src:libdouble_conversion",
     "..:generate_version_cc_file",
@@ -143,7 +143,7 @@
 executable("gen_snapshot") {
   configs += ["..:dart_config"]
   deps = [
-    ":libdart_withcore",
+    ":libdart_nosnapshot",
     ":libdart_builtin",
   ]
 
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 863430c..18f5aec 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -506,6 +506,7 @@
           'action': [
             'python',
             'tools/create_resources.py',
+            '--compress',
             '--output', '<(resources_cc_file)',
             '--outer_namespace', 'dart',
             '--inner_namespace', 'bin',
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index fe18de3..940556a 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -4,6 +4,7 @@
 
 library builtin;
 // NOTE: Do not import 'dart:io' in builtin.
+import 'dart:collection';
 import 'dart:isolate';
 import 'dart:typed_data';
 
@@ -59,9 +60,17 @@
 
 // A port for communicating with the service isolate for I/O.
 SendPort _loadPort;
-// Maintain a number of outstanding load requests. Current loading request is
-// finished once there are no outstanding requests.
-int _numOutstandingLoadRequests = 0;
+// The receive port for a load request. Multiple sources can be fetched in
+// a single load request.
+RawReceivePort _receivePort;
+SendPort _sendPort;
+// A request id valid only for the current load cycle (while the number of
+// outstanding load requests is greater than 0). Can be reset when loading is
+// completed.
+int _reqId = 0;
+// An unordered hash map mapping from request id to a particular load request.
+// Once there are no outstanding load requests the current load has finished.
+HashMap _reqMap = new HashMap();
 
 // The current working directory when the embedder was launched.
 Uri _workingDirectory;
@@ -80,11 +89,22 @@
 
 
 // A class wrapping the load error message in an Error object.
-class LoadError extends Error {
+class _LoadError extends Error {
   final String message;
-  LoadError(this.message);
+  final String uri;
+  _LoadError(this.uri, this.message);
 
-  String toString() => 'Load Error: $message';
+  String toString() => 'Load Error for "$uri": $message';
+}
+
+// Class collecting all of the information about a particular load request.
+class _LoadRequest {
+  final int _id;
+  final int _tag;
+  final String _uri;
+  final String _libraryUri;
+
+  _LoadRequest(this._id, this._tag, this._uri, this._libraryUri);
 }
 
 
@@ -229,49 +249,104 @@
 }
 
 
-void _finishLoadRequest(String uri) {
-  assert(_numOutstandingLoadRequests > 0);
-  _numOutstandingLoadRequests--;
+void _finishLoadRequest(_LoadRequest req) {
+  // Now that we are done with loading remove the request from the map.
+  var tmp = _reqMap.remove(req._id);
+  assert(tmp == req);
   if (_traceLoading) {
-    _print("Loading of $uri finished, "
-           "${_numOutstandingLoadRequests} requests remaining");
+    _print("Loading of ${req._uri} finished, "
+    "${_reqMap.length} requests remaining");
   }
-  if (_numOutstandingLoadRequests == 0) {
+
+  if (_reqMap.isEmpty) {
+    if (_traceLoading) {
+      _print("Closing loading port.");
+    }
+    _receivePort.close();
+    _receivePort = null;
+    _sendPort = null;
+    _reqId = 0;
     _signalDoneLoading();
   }
 }
 
 
-void _startLoadRequest(String uri, Uri resourceUri) {
-  assert(_numOutstandingLoadRequests >= 0);
-  _numOutstandingLoadRequests++;
-  if (_traceLoading) {
-    _print("Loading of $resourceUri for $uri started, "
-           "${_numOutstandingLoadRequests} requests outstanding");
+void _handleLoaderReply(msg) {
+  int id = msg[0];
+  var dataOrError = msg[1];
+  assert((id >= 0) && (id < _reqId));
+  var req = _reqMap[id];
+  try {
+    if (dataOrError is Uint8List) {
+      _loadScript(req, dataOrError);
+    } else {
+      assert(dataOrError is String);
+      var error = new _LoadError(req._uri, dataOrError.toString());
+      _asyncLoadError(req, error);
+    }
+  } catch(e, s) {
+    // Wrap inside a _LoadError unless we are already propagating a
+    // previous _LoadError.
+    var error = (e is _LoadError) ? e : new _LoadError(req._uri, e.toString());
+    assert(req != null);
+    _asyncLoadError(req, error);
   }
 }
 
 
-void _loadScript(int tag, String uri, String libraryUri, Uint8List data) {
+void _startLoadRequest(int tag,
+                       String uri,
+                       String libraryUri,
+                       Uri resourceUri) {
+  if (_reqMap.isEmpty) {
+    if (_traceLoading) {
+      _print("Initializing load port.");
+    }
+    assert(_receivePort == null);
+    assert(_sendPort == null);
+    _receivePort = new RawReceivePort(_handleLoaderReply);
+    _sendPort = _receivePort.sendPort;
+  }
+  // Register the load request and send it to the VM service isolate.
+  var curId = _reqId++;
+
+  assert(_reqMap[curId] == null);
+  _reqMap[curId] = new _LoadRequest(curId, tag, uri, libraryUri);
+
+  var msg = new List(3);
+  msg[0] = _sendPort;
+  msg[1] = curId;
+  msg[2] = resourceUri.toString();
+  _loadPort.send(msg);
+
+  if (_traceLoading) {
+    _print("Loading of $resourceUri for $uri started with id: $curId, "
+           "${_reqMap.length} requests outstanding");
+  }
+}
+
+
+void _loadScript(_LoadRequest req, Uint8List data) {
   // TODO: Currently a compilation error while loading the script is
   // fatal for the isolate. _loadScriptCallback() does not return and
-  // the _numOutstandingLoadRequests counter remains out of sync.
-  _loadScriptCallback(tag, uri, libraryUri, data);
-  _finishLoadRequest(uri);
+  // the number of requests remains out of sync.
+  _loadScriptCallback(req._tag, req._uri, req._libraryUri, data);
+  _finishLoadRequest(req);
 }
 
 
-void _asyncLoadError(int tag, String uri, String libraryUri, LoadError error) {
+void _asyncLoadError(_LoadRequest req, _LoadError error) {
   if (_traceLoading) {
-    _print("_asyncLoadError($uri), error: $error");
+    _print("_asyncLoadError(${req._uri}), error: $error");
   }
-  if (tag == Dart_kImportTag) {
+  var libraryUri = req._libraryUri;
+  if (req._tag == Dart_kImportTag) {
     // When importing a library, the libraryUri is the imported
     // uri.
-    libraryUri = uri;
+    libraryUri = req._uri;
   }
-  _asyncLoadErrorCallback(uri, libraryUri, error);
-  _finishLoadRequest(uri);
+  _asyncLoadErrorCallback(req._uri, libraryUri, error);
+  _finishLoadRequest(req);
 }
 
 
@@ -279,37 +354,16 @@
                       String uri,
                       String libraryUri,
                       Uri resourceUri) {
-  var receivePort = new ReceivePort();
-  receivePort.first.then((dataOrError) {
-    receivePort.close();
-    if (dataOrError is Uint8List) {
-      _loadScript(tag, uri, libraryUri, dataOrError);
-    } else {
-      assert(dataOrError is String);
-      var error = new LoadError(dataOrError.toString());
-      _asyncLoadError(tag, uri, libraryUri, error);
-    }
-  }).catchError((e) {
-    receivePort.close();
-    // Wrap inside a LoadError unless we are already propagating a previously
-    // seen LoadError.
-    var error = (e is LoadError) ? e : new LoadError(e.toString);
-    _asyncLoadError(tag, uri, libraryUri, error);
-  });
-
   try {
-    var msg = [receivePort.sendPort, resourceUri.toString()];
-    _loadPort.send(msg);
-    _startLoadRequest(uri, resourceUri);
+    _startLoadRequest(tag, uri, libraryUri, resourceUri);
   } catch (e) {
     if (_traceLoading) {
       _print("Exception when communicating with service isolate: $e");
     }
-    // Wrap inside a LoadError unless we are already propagating a previously
-    // seen LoadError.
-    var error = (e is LoadError) ? e : new LoadError(e.toString);
+    // Wrap inside a _LoadError unless we are already propagating a previously
+    // seen _LoadError.
+    var error = (e is _LoadError) ? e : new _LoadError(e.toString());
     _asyncLoadError(tag, uri, libraryUri, error);
-    receivePort.close();
   }
 }
 
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index b55575d..544cf32 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -516,7 +516,8 @@
 
 
 int main(int argc, char** argv) {
-  CommandLineOptions vm_options(argc);
+  const int EXTRA_VM_ARGUMENTS = 1;
+  CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
 
   // Initialize the URL mapping array.
   CommandLineOptions url_mapping_array(argc);
@@ -534,6 +535,8 @@
   Thread::InitOnce();
   DartUtils::SetOriginalWorkingDirectory();
 
+  vm_options.AddArgument("--load_deferred_eagerly");
+
   Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
 
   // Initialize the Dart VM.
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index a5c3563..7bb98a1 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -872,7 +872,8 @@
 
 void main(int argc, char** argv) {
   char* script_name;
-  CommandLineOptions vm_options(argc);
+  const int EXTRA_VM_ARGUMENTS = 2;
+  CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
   CommandLineOptions dart_options(argc);
   bool print_flags_seen = false;
   bool verbose_debug_seen = false;
@@ -921,6 +922,10 @@
     exit(kErrorExitCode);
   }
 
+  if (generate_script_snapshot) {
+    vm_options.AddArgument("--load_deferred_eagerly");
+  }
+
   Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
 
   // Start event handler.
diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc
index f7a2920..2f55f9d 100644
--- a/runtime/bin/platform.cc
+++ b/runtime/bin/platform.cc
@@ -13,6 +13,7 @@
 namespace bin {
 
 const char* Platform::executable_name_ = NULL;
+bool Platform::executable_name_resolved_ = false;
 const char* Platform::package_root_ = NULL;
 int Platform::script_index_ = 1;
 char** Platform::argv_ = NULL;
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index 78cb33d..6b81539 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -39,11 +39,21 @@
   static char** Environment(intptr_t* count);
   static void FreeEnvironment(char** env, intptr_t count);
 
-  // Stores and gets the executable name.
+  static char* ResolveExecutablePath();
+
+  // Stores the executable name.
   static void SetExecutableName(const char* executable_name) {
     executable_name_ = executable_name;
   }
   static const char* GetExecutableName() {
+    if (!executable_name_resolved_) {
+      // Try to resolve the executable path using platform specific APIs.
+      char* path = Platform::ResolveExecutablePath();
+      if (path != NULL) {
+        executable_name_ = path;
+      }
+      executable_name_resolved_ = true;
+    }
     return executable_name_;
   }
 
@@ -68,7 +78,11 @@
   }
 
  private:
+  // The path to the executable.
   static const char* executable_name_;
+  // State to indicate whether the executable name has been resolved.
+  static bool executable_name_resolved_;
+
   static const char* package_root_;
   static int script_index_;
   static char** argv_;  // VM flags are argv_[1 ... script_index_ - 1]
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index b1e7d33..dddb4e1 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -5,6 +5,7 @@
 #include "platform/globals.h"
 #if defined(TARGET_OS_ANDROID)
 
+#include "bin/file.h"
 #include "bin/platform.h"
 
 #include <signal.h>  // NOLINT
@@ -71,6 +72,11 @@
   delete[] env;
 }
 
+
+char* Platform::ResolveExecutablePath() {
+  return File::LinkTarget("/proc/self/exe");
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index f6dfaa1..8469a21 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -5,6 +5,7 @@
 #include "platform/globals.h"
 #if defined(TARGET_OS_LINUX)
 
+#include "bin/file.h"
 #include "bin/platform.h"
 
 #include <signal.h>  // NOLINT
@@ -71,6 +72,11 @@
   delete[] env;
 }
 
+
+char* Platform::ResolveExecutablePath() {
+  return File::LinkTarget("/proc/self/exe");
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 55ccd21..702bf01 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -5,6 +5,8 @@
 #include "platform/globals.h"
 #if defined(TARGET_OS_MACOS)
 
+#include <mach-o/dyld.h>
+
 #include "bin/platform.h"
 
 #include <crt_externs.h>  // NOLINT
@@ -75,6 +77,23 @@
   delete[] env;
 }
 
+
+char* Platform::ResolveExecutablePath() {
+  // Get the required length of the buffer.
+  uint32_t path_size = 0;
+  char* path = NULL;
+  if (_NSGetExecutablePath(path, &path_size) == 0) {
+    return NULL;
+  }
+  // Allocate buffer and get executable path.
+  path = reinterpret_cast<char*>(malloc(path_size));
+  if (_NSGetExecutablePath(path, &path_size) != 0) {
+    free(path);
+    return NULL;
+  }
+  return path;
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index 97d54cc..afa924b 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -80,6 +80,26 @@
   delete[] env;
 }
 
+
+char* Platform::ResolveExecutablePath() {
+  // GetModuleFileNameW cannot directly provide information on the
+  // required buffer size, so start out with a buffer large enough to
+  // hold any Windows path.
+  const int kTmpBufferSize = 32768;
+  wchar_t* tmp_buffer = reinterpret_cast<wchar_t*>(malloc(kTmpBufferSize));
+  // Ensure no last error before calling GetModuleFileNameW.
+  SetLastError(ERROR_SUCCESS);
+  // Get the required length of the buffer.
+  int path_length = GetModuleFileNameW(NULL, tmp_buffer, kTmpBufferSize);
+  if (GetLastError() != ERROR_SUCCESS) {
+    free(tmp_buffer);
+    return NULL;
+  }
+  char* path = StringUtils::WideToUtf8(tmp_buffer);
+  free(tmp_buffer);
+  return path;
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/vmservice/loader.dart b/runtime/bin/vmservice/loader.dart
index 2e04455..ce3c9cc 100644
--- a/runtime/bin/vmservice/loader.dart
+++ b/runtime/bin/vmservice/loader.dart
@@ -6,7 +6,16 @@
 
 var _httpClient;
 
-void _loadHttp(sendPort, uri) {
+// Send a response to the requesting isolate.
+void _sendResponse(SendPort sp, int id, dynamic data) {
+  assert((data is List<int>) || (data is String));
+  var msg = new List(2);
+  msg[0] = id;
+  msg[1] = data;
+  sp.send(msg);
+}
+
+void _loadHttp(SendPort sp, int id, Uri uri) {
   if (_httpClient == null) {
     _httpClient = new HttpClient()..maxConnectionsPerHost = 6;
   }
@@ -18,39 +27,41 @@
           builder.add,
           onDone: () {
             if (response.statusCode != 200) {
-              var msg = 'Failure getting $uri: '
-                        '${response.statusCode} ${response.reasonPhrase}';
-              sendPort.send(msg);
+              var msg = "Failure getting $uri:\n"
+                        "  ${response.statusCode} ${response.reasonPhrase}";
+              _sendResponse(sp, id, msg);
             } else {
-              sendPort.send(builder.takeBytes());
+              _sendResponse(sp, id, builder.takeBytes());
             }
           },
           onError: (e) {
-            sendPort.send(e.toString());
+            _sendResponse(sp, d, e.toString());
           });
     })
     .catchError((e) {
-      sendPort.send(e.toString());
+      _sendResponse(sp, id, e.toString());
     });
   // It's just here to push an event on the event loop so that we invoke the
   // scheduled microtasks.
   Timer.run(() {});
 }
 
-void _loadFile(sendPort, path) {
+void _loadFile(SendPort sp, int id, Uri uri) {
+  var path = uri.toFilePath();
   var sourceFile = new File(path);
   sourceFile.readAsBytes().then((data) {
-    sendPort.send(data);
+    _sendResponse(sp, id, data);
   },
   onError: (e) {
-    sendPort.send(e.toString());
+    var err = "Error loading $uri:\n  $e";
+    _sendResponse(sp, id, err);
   });
 }
 
 var dataUriRegex = new RegExp(
     r"data:([\w-]+/[\w-]+)?(;charset=([\w-]+))?(;base64)?,(.*)");
 
-void _loadDataUri(sendPort, uri) {
+void _loadDataUri(SendPort sp, int id, Uri uri) {
   try {
     var match = dataUriRegex.firstMatch(uri.toString());
     if (match == null) throw "Malformed data uri";
@@ -72,21 +83,23 @@
     }
 
     var data = UTF8.encode(Uri.decodeComponent(encodedData));
-    sendPort.send(data);
+    _sendResponse(sp, id, data);
   } catch (e) {
-    sendPort.send("Invalid data uri ($uri) $e");
+    _sendResponse(sp, id, "Invalid data uri ($uri):\n  $e");
   }
 }
 
 _processLoadRequest(request) {
-  var sp = request[0];
-  var uri = Uri.parse(request[1]);
+  SendPort sp = request[0];
+  int id = request[1];
+  String resource = request[2];
+  var uri = Uri.parse(request[2]);
   if (uri.scheme == 'file') {
-    _loadFile(sp, uri.toFilePath());
+    _loadFile(sp, id, uri);
   } else if ((uri.scheme == 'http') || (uri.scheme == 'https')) {
-    _loadHttp(sp, uri);
+    _loadHttp(sp, id, uri);
   } else if ((uri.scheme == 'data')) {
-    _loadDataUri(sp, uri);
+    _loadDataUri(sp, id, uri);
   } else {
     sp.send('Unknown scheme (${uri.scheme}) for $uri');
   }
diff --git a/runtime/bin/vmservice/resources.dart b/runtime/bin/vmservice/resources.dart
index 0930fdc..9153455 100644
--- a/runtime/bin/vmservice/resources.dart
+++ b/runtime/bin/vmservice/resources.dart
@@ -40,9 +40,21 @@
   static final Map<String, Resource> resources = new Map<String, Resource>();
 }
 
+ZLibCodec _zlib;
 
-void _addResource(String name, List<int> data) {
+void _addResource(String name, List<int> data, bool compressed) {
   var mimeType = detectMimeType(name);
+  if (compressed) {
+    if (_zlib == null) {
+      _zlib = new ZLibCodec();
+    }
+    try {
+      data = _zlib.decode(data);
+    } catch(e) {
+      print('error decompressing service isolate resource: $name');
+      return;
+    }
+  }
   Resource resource = new Resource(name, mimeType, data);
   Resource.resources[name] = resource;
 }
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index e830389..d59be63 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -318,8 +318,9 @@
   RETURN_ERROR_HANDLE(result);
 
   // Make invoke call.
-  const intptr_t kNumArgs = 2;
-  Dart_Handle args[kNumArgs] = { name, data_list };
+  const intptr_t kNumArgs = 3;
+  Dart_Handle compressed = Dart_True();
+  Dart_Handle args[kNumArgs] = { name, data_list, compressed };
   result = Dart_Invoke(library, Dart_NewStringFromCString("_addResource"),
                        kNumArgs, args);
   return result;
diff --git a/runtime/lib/developer_sources.gypi b/runtime/lib/developer_sources.gypi
index 4bedb67..4d4218c 100644
--- a/runtime/lib/developer_sources.gypi
+++ b/runtime/lib/developer_sources.gypi
@@ -8,6 +8,8 @@
   'sources': [
     'developer.cc',
     'developer.dart',
+    'profiler.cc',
+    'profiler.dart',
   ],
 }
 
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index c44d18d..1ee5b25 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -301,7 +301,7 @@
     // Shift count is too large..
     const Instance& exception =
         Instance::Handle(isolate->object_store()->out_of_memory());
-    Exceptions::Throw(isolate, exception);
+    Exceptions::Throw(thread, exception);
   }
   const Smi& smi_shift_count = Smi::Cast(shift_count);
   const Integer& shift_result = Integer::Handle(
@@ -395,7 +395,7 @@
   // into dart code or allocating any code.
   const Instance& exception =
       Instance::Handle(isolate->object_store()->out_of_memory());
-  Exceptions::Throw(isolate, exception);
+  Exceptions::Throw(thread, exception);
   UNREACHABLE();
   return 0;
 }
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 1f72dc2..1e08dad 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -56,7 +56,7 @@
 DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 1) {
   ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull());
   Dart_Port port_id =
-      PortMap::CreatePort(arguments->isolate()->message_handler());
+      PortMap::CreatePort(isolate->message_handler());
   return ReceivePort::New(port_id, false /* not control port */);
 }
 
@@ -255,8 +255,8 @@
   char* error = NULL;
   char* canonical_uri = NULL;
   const Library& root_lib =
-      Library::Handle(arguments->isolate()->object_store()->root_library());
-  if (!CanonicalizeUri(arguments->isolate(), root_lib, uri,
+      Library::Handle(isolate->object_store()->root_library());
+  if (!CanonicalizeUri(isolate, root_lib, uri,
                        &canonical_uri, &error)) {
     const String& msg = String::Handle(String::New(error));
     ThrowIsolateSpawnException(msg);
diff --git a/runtime/lib/profiler.cc b/runtime/lib/profiler.cc
index a734250..7959360 100644
--- a/runtime/lib/profiler.cc
+++ b/runtime/lib/profiler.cc
@@ -15,7 +15,7 @@
 
 DECLARE_FLAG(bool, trace_intrinsified_natives);
 
-// dart:profiler.
+// Native implementations of the profiler parts of the dart:developer library.
 
 DEFINE_NATIVE_ENTRY(UserTag_new, 2) {
   ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull());
diff --git a/runtime/lib/profiler_sources.gypi b/runtime/lib/profiler_sources.gypi
index 4d5ee05..9175427 100644
--- a/runtime/lib/profiler_sources.gypi
+++ b/runtime/lib/profiler_sources.gypi
@@ -1,13 +1,12 @@
-# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+# 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.
 
-# Sources visible via dart:profiler library.
+# Sources list to keep vm/BUILD.gn generate_core_libraries happy.
 
 {
   'sources': [
-    'profiler.cc',
-    'profiler.dart',
+    'empty_source.dart'
   ],
 }
 
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index 4fb7fff..a6d5dfd 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -1266,7 +1266,7 @@
   }
 
   void _setIndexedUint32(int index, int value) {
-    _setInt32(index * Uint32List.BYTES_PER_ELEMENT, value);
+    _setUint32(index * Uint32List.BYTES_PER_ELEMENT, value);
   }
 
   static _Uint32Array _new(int length) native "TypedData_Uint32Array_new";
@@ -1940,7 +1940,7 @@
   }
 
   void _setIndexedUint32(int index, int value) {
-    _setInt32(index * Uint32List.BYTES_PER_ELEMENT, value);
+    _setUint32(index * Uint32List.BYTES_PER_ELEMENT, value);
   }
 
   static _ExternalUint32Array _new(int length) native
diff --git a/runtime/observatory/lib/dominator_tree.dart b/runtime/observatory/lib/dominator_tree.dart
deleted file mode 100644
index 62106c3..0000000
--- a/runtime/observatory/lib/dominator_tree.dart
+++ /dev/null
@@ -1,121 +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 dominator_tree;
-
-// Flowgraph dominators in O(m log n) time. Implements the algorithm from
-// [Lengauer & Tarjan 1979]
-// T. Lengauer and R.E. Tarjan,
-// "A fast algorithm for finding dominators in a flowgraph",
-// ACM Transactions on Programming Language and Systems, 1(1):121-141, 1979.
-
-// Internal vertex information used inside 'Dominator'.
-// Field names mostly follow naming in [Lengauer & Tarjan 1979].
-class _Vertex {
-  final Object id;
-  _Vertex dom;
-  _Vertex parent;
-  _Vertex ancestor;
-  _Vertex label;
-  int semi;
-  final List<_Vertex> pred = new List<_Vertex>();
-  final List<_Vertex> bucket = new List<_Vertex>();
-  // TODO(koda): Avoid duplication by having an interface for 'id' with
-  // access to outgoing edges, and/or clearing 'succ' after constructing
-  // inverse graph in 'pred'.
-  final List<_Vertex> succ = new List<_Vertex>();
-  _Vertex(this.id) { label = this; }
-}
-
-// Utility to compute immediate dominators. Usage:
-// 1. Build the flowgraph using 'addEdges'.
-// 2. Call 'computeDominatorTree' once.
-// 3. Use 'dominator' to access result.
-// The instance can only be used once.
-class Dominator {
-  final Map<Object, _Vertex> _idToVertex = new Map<Object, _Vertex>();
-  final List<_Vertex> _vertex = new List<_Vertex>();
-  
-  void addEdges(Object u, Iterable<Object> vs) {
-    _asVertex(u).succ.addAll(vs.map(_asVertex));
-  }
-  
-  // Returns the immediate dominator of 'v', or null if 'v' is the root.
-  Object dominator(Object v) {
-    _Vertex dom = _asVertex(v).dom;
-    return dom == null ? null : dom.id;
-  }
-  
-  _Vertex _asVertex(Object u) {
-    return _idToVertex.putIfAbsent(u, () => new _Vertex(u));
-  }
-  
-  void _dfs(_Vertex v) {
-    v.semi = _vertex.length;
-    _vertex.add(v);
-    for (_Vertex w in v.succ) {
-      if (w.semi == null) {
-        w.parent = v;
-        _dfs(w);
-      }
-      w.pred.add(v);
-    }
-  }
-
-  void _compress(_Vertex v) {
-    if (v.ancestor.ancestor != null) {
-      _compress(v.ancestor);
-      if (v.ancestor.label.semi < v.label.semi) {
-        v.label = v.ancestor.label;
-      }
-      v.ancestor = v.ancestor.ancestor;
-    }
-  }
-
-  _Vertex _eval(_Vertex v) {
-    if (v.ancestor == null) {
-      return v;
-    } else {
-      _compress(v);
-      return v.label;
-    }
-  }
-
-  void _link(_Vertex v, _Vertex w) {
-    w.ancestor = v;
-  }
-
-  void computeDominatorTree(Object root) {
-    _Vertex r = _asVertex(root);
-    int n = _idToVertex.length;
-    _dfs(r);
-    if (_vertex.length != n) {
-      throw new StateError("Not a flowgraph: "
-          "only ${_vertex.length} of $n vertices reachable");
-    }
-    for (int i = n - 1; i >= 1; --i) {
-      _Vertex w = _vertex[i];
-      for (_Vertex v in w.pred) {
-        _Vertex u = _eval(v);
-        if (u.semi < w.semi) {
-          w.semi = u.semi;
-        }
-      }
-      _vertex[w.semi].bucket.add(w);
-      _link(w.parent, w);
-      for (_Vertex v in w.parent.bucket) {
-        _Vertex u = _eval(v);
-        v.dom = u.semi < v.semi ? u : w.parent;
-      }
-      w.parent.bucket.clear();
-    }
-    for (int i = 1; i < n; ++i) {
-      _Vertex w = _vertex[i];
-      if (w.dom != _vertex[w.semi]) {
-        w.dom = w.dom.dom;
-      }
-    }
-    r.dom = null;
-  }
-}
\ No newline at end of file
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index 502fba8..72ff047 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -23,6 +23,7 @@
 export 'package:observatory/src/elements/general_error.dart';
 export 'package:observatory/src/elements/heap_map.dart';
 export 'package:observatory/src/elements/heap_profile.dart';
+export 'package:observatory/src/elements/heap_snapshot.dart';
 export 'package:observatory/src/elements/instance_ref.dart';
 export 'package:observatory/src/elements/instance_view.dart';
 export 'package:observatory/src/elements/io_view.dart';
diff --git a/runtime/observatory/lib/object_graph.dart b/runtime/observatory/lib/object_graph.dart
index 9c9ad34..a616043 100644
--- a/runtime/observatory/lib/object_graph.dart
+++ b/runtime/observatory/lib/object_graph.dart
@@ -4,29 +4,45 @@
 
 library object_graph;
 
+import 'dart:async';
+import 'dart:collection';
 import 'dart:typed_data';
 
-import 'dominator_tree.dart';
+import 'package:logging/logging.dart';
 
 // Port of dart::ReadStream from vm/datastream.h.
-class ReadStream {
-  int _cur = 0;
-  final ByteData _data;
-  
-  ReadStream(this._data);
-  
-  int get pendingBytes => _data.lengthInBytes - _cur;
-  
+class _ReadStream {
+  int position = 0;
+  int _size = 0;
+  final List<ByteData> _chunks;
+
+  _ReadStream(this._chunks) {
+    int n = _chunks.length;
+    for (var i = 0; i < n; i++) {
+      var chunk = _chunks[i];
+      if (i + 1 != n) {
+        assert(chunk.lengthInBytes == (1 << 20));
+      }
+      _size += chunk.lengthInBytes;
+    }
+  }
+
+  int get pendingBytes => _size - position;
+
+  int getUint8(i) {
+    return _chunks[i >> 20].getUint8(i & 0xFFFFF);
+  }
+
   int readUnsigned() {
     int result = 0;
     int shift = 0;
-    while (_data.getUint8(_cur) <= maxUnsignedDataPerByte) {
-      result |= _data.getUint8(_cur) << shift;
+    while (getUint8(position) <= maxUnsignedDataPerByte) {
+      result |= getUint8(position) << shift;
       shift += dataBitsPerByte;
-      ++_cur;
+      position++;
     }
-    result |= (_data.getUint8(_cur) & byteMask) << shift;
-    ++_cur;
+    result |= (getUint8(position) & byteMask) << shift;
+    position++;
     return result;
   }
 
@@ -36,59 +52,138 @@
 }
 
 class ObjectVertex {
-  // Never null. The isolate root has id 0.
+  // 0 represents invalid/uninitialized, 1 is the root.
   final int _id;
-  bool get isRoot => _id == 0;
-  // TODO(koda): Include units in object graph metadata.
-  int addressForWordSize(int bytesPerWord) => _id * 2 * bytesPerWord;
-  // null for VM-heap objects.
-  int _shallowSize;
-  int get shallowSize => _shallowSize;
-  int _retainedSize;
-  int get retainedSize => _retainedSize;
-  // null for VM-heap objects.
-  int _classId;
-  int get classId => _classId;
-  final List<ObjectVertex> succ = new List<ObjectVertex>();
-  ObjectVertex(this._id) : _retainedSize = 0;
-  String toString() => '$_id,$_shallowSize,$succ';
+  final ObjectGraph _graph;
+
+  ObjectVertex._(this._id, this._graph);
+
+  bool operator ==(other) => _id == other._id && _graph == other._graph;
+  int get hashCode => _id;
+
+  int get retainedSize => _graph._retainedSizes[_id];
+  ObjectVertex get dominator => new ObjectVertex._(_graph._doms[_id], _graph);
+
+  int get shallowSize {
+    var stream = new _ReadStream(_graph._chunks);
+    stream.position = _graph._positions[_id];
+    stream.readUnsigned(); // addr
+    return stream.readUnsigned(); // shallowSize
+  }
+
+  int get vmCid {
+    var stream = new _ReadStream(_graph._chunks);
+    stream.position = _graph._positions[_id];
+    stream.readUnsigned(); // addr
+    stream.readUnsigned(); // shallowSize
+    return stream.readUnsigned(); // cid
+  }
+
+  get successors => new _SuccessorsIterable(_graph, _id);
+
+  int get address {
+    // Note that everywhere else in this file, "address" really means an address
+    // scaled down by kObjectAlignment. They were scaled down so they would fit
+    // into Smis on the client.
+    var stream = new _ReadStream(_graph._chunks);
+    stream.position = _graph._positions[_id];
+    var scaledAddr = stream.readUnsigned();
+    return scaledAddr * _graph._kObjectAlignment;
+  }
+
+  List<ObjectVertex> dominatorTreeChildren() {
+    var N = _graph._N;
+    var doms = _graph._doms;
+
+    var parentId = _id;
+    var domChildren = [];
+
+    for (var childId = 1; childId <= N; childId++) {
+      if (doms[childId] == parentId) {
+        domChildren.add(new ObjectVertex._(childId, _graph));
+      }
+    }
+
+    return domChildren;
+  }
 }
 
-// See implementation of ObjectGraph::Serialize for format.
+class _SuccessorsIterable extends IterableBase<ObjectVertex> {
+  final ObjectGraph _graph;
+  final int _id;
+
+  _SuccessorsIterable(this._graph, this._id);
+
+  Iterator<ObjectVertex> get iterator => new _SuccessorsIterator(_graph, _id);
+}
+
+class _SuccessorsIterator implements Iterator<ObjectVertex> {
+  final ObjectGraph _graph;
+  _ReadStream _stream;
+
+  ObjectVertex current;
+
+  _SuccessorsIterator(this._graph, int id) {
+    _stream = new _ReadStream(this._graph._chunks);
+    _stream.position = _graph._positions[id];
+    _stream.readUnsigned(); // addr
+    _stream.readUnsigned(); // shallowSize
+    var cid = _stream.readUnsigned();
+    assert((cid & ~0xFFFF) == 0); // Sanity check: cid's are 16 bit.
+  }
+
+  bool moveNext() {
+    while (true) {
+      var nextAddr = _stream.readUnsigned();
+      if (nextAddr == 0) return false;
+      var nextId = _graph._addrToId[nextAddr];
+      if (nextId == null) continue; // Reference to VM isolate's heap.
+      current = new ObjectVertex._(nextId, _graph);
+      return true;
+    }
+  }
+}
+
+class _VerticesIterable extends IterableBase<ObjectVertex> {
+  final ObjectGraph _graph;
+
+  _VerticesIterable(this._graph);
+
+  Iterator<ObjectVertex> get iterator => new _VerticesIterator(_graph);
+}
+
+class _VerticesIterator implements Iterator<ObjectVertex> {
+  final ObjectGraph _graph;
+
+  int _nextId = 0;
+  ObjectVertex current;
+
+  _VerticesIterator(this._graph);
+
+  bool moveNext() {
+    if (_nextId == _graph._N) return false;
+    current = new ObjectVertex._(_nextId++, _graph);
+    return true;
+  }
+}
+
 class ObjectGraph {
-  final Map<int, ObjectVertex> _idToVertex = new Map<int, ObjectVertex>();
+  ObjectGraph(List<ByteData> chunks, int nodeCount)
+    : this._chunks = chunks
+    , this._N = nodeCount;
 
-  ObjectVertex _asVertex(int id) {
-    return _idToVertex.putIfAbsent(id, () => new ObjectVertex(id));
-  }
+  int get size => _size;
+  int get vertexCount => _N;
+  int get edgeCount => _E;
 
-  void _addFrom(ReadStream stream) {
-    ObjectVertex obj = _asVertex(stream.readUnsigned());
-    obj._shallowSize = stream.readUnsigned();
-    obj._classId = stream.readUnsigned();
-    int last = stream.readUnsigned();
-    while (last != 0) {
-      obj.succ.add(_asVertex(last));
-      last = stream.readUnsigned();
-    }
-  }
+  ObjectVertex get root => new ObjectVertex._(1, this);
+  Iterable<ObjectVertex> get vertices => new _VerticesIterable(this);
 
-  ObjectGraph(ReadStream reader) {
-    while (reader.pendingBytes > 0) {
-      _addFrom(reader);
-    }
-    _computeRetainedSizes();
-    _mostRetained = new List<ObjectVertex>.from(
-        vertices.where((u) => !u.isRoot));
-    _mostRetained.sort((u, v) => v.retainedSize - u.retainedSize);
-  }
-
-  Iterable<ObjectVertex> get vertices => _idToVertex.values;
-  List<ObjectVertex> _mostRetained;
-
-  ObjectVertex get root => _asVertex(0);
-  
   Iterable<ObjectVertex> getMostRetained({int classId, int limit}) {
+    List<ObjectVertex> _mostRetained =
+      new List<ObjectVertex>.from(vertices.where((u) => !u.isRoot));
+    _mostRetained.sort((u, v) => v.retainedSize - u.retainedSize);
+
     var result = _mostRetained;
     if (classId != null) {
       result = result.where((u) => u.classId == classId);
@@ -98,41 +193,326 @@
     }
     return result;
   }
-  
-  void _computeRetainedSizes() {
-    // The retained size for an object is the sum of the shallow sizes of
-    // all its descendants in the dominator tree (including itself).
-    var d = new Dominator();
-    for (ObjectVertex u in vertices) {
-      if (u.shallowSize != null) {
-        u._retainedSize = u.shallowSize;
-        d.addEdges(u, u.succ.where((ObjectVertex v) => v.shallowSize != null));
-      }
-    }
-    d.computeDominatorTree(root);
-    // Compute all retained sizes "bottom up", starting from the leaves.
-    // Keep track of number of remaining children of each vertex.
-    var degree = new Map<ObjectVertex, int>();
-    for (ObjectVertex u in vertices) {
-      var v = d.dominator(u);
-      if (v != null) {
-        degree[v] = 1 + degree.putIfAbsent(v, () => 0);
-      }
-    }
-    var leaves = new List<ObjectVertex>();
-    for (ObjectVertex u in vertices) {
-      if (!degree.containsKey(u)) {
-        leaves.add(u);
-      }
-    }
-    while (!leaves.isEmpty) {
-      var v = leaves.removeLast();
-      var u = d.dominator(v);
-      if (u == null) continue;
-      u._retainedSize += v._retainedSize;
-      if (--degree[u] == 0) {
-        leaves.add(u);
-      }
-    }
+
+  Future process(statusReporter) async {
+    // We build futures here instead of marking the steps as async to avoid the
+    // heavy lifting being inside a transformed method.
+
+    statusReporter.add("Finding node positions...");
+    await new Future(() => _buildPositions());
+
+    statusReporter.add("Finding post order...");
+    await new Future(() => _buildPostOrder());
+
+    statusReporter.add("Finding predecessors...");
+    await new Future(() => _buildPredecessors());
+
+    statusReporter.add("Finding dominators...");
+    await new Future(() => _buildDominators());
+
+    _firstPreds = null;
+    _preds = null;
+    _postOrderIndices = null;
+
+    statusReporter.add("Finding retained sizes...");
+    await new Future(() => _calculateRetainedSizes());
+
+    _postOrderOrdinals = null;
+
+    statusReporter.add("Loaded");
+    return this;
   }
-}
\ No newline at end of file
+
+  final List<ByteData> _chunks;
+
+  int _kObjectAlignment;
+  int _N;
+  int _E;
+  int _size;
+
+  Map<int, int> _addrToId = new Map<int, int>();
+
+  // Indexed by node id, with id 0 representing invalid/uninitialized.
+  Uint32List _positions; // Position of the node in the snapshot.
+  Uint32List _postOrderOrdinals; // post-order index -> id
+  Uint32List _postOrderIndices; // id -> post-order index
+  Uint32List _firstPreds; // Offset into preds.
+  Uint32List _preds;
+  Uint32List _doms;
+  Uint32List _retainedSizes;
+
+  void _buildPositions() {
+    var N = _N;
+    var addrToId = _addrToId;
+
+    var positions = new Uint32List(N + 1);
+
+    var stream = new _ReadStream(_chunks);
+    _kObjectAlignment = stream.readUnsigned();
+
+    var id = 1;
+    while (stream.pendingBytes > 0) {
+      positions[id] = stream.position;
+      var addr = stream.readUnsigned();
+      var shallowSize = stream.readUnsigned();
+      var cid = stream.readUnsigned();
+      addrToId[addr] = id;
+
+      var succAddr = stream.readUnsigned();
+      while (succAddr != 0) {
+        succAddr = stream.readUnsigned();
+      }
+      id++;
+    }
+    assert(id == (N + 1));
+
+    var root = addrToId[0];
+    assert(root == 1);
+
+    _positions = positions;
+  }
+
+  void _buildPostOrder() {
+    var N = _N;
+    var E = 0;
+    var addrToId = _addrToId;
+    var positions = _positions;
+
+    var postOrderOrdinals = new Uint32List(N);
+    var postOrderIndices = new Uint32List(N + 1);
+    var stackNodes = new Uint32List(N);
+    var stackCurrentEdgePos = new Uint32List(N);
+
+    var visited = new Uint8List(N + 1);
+    var postOrderIndex = 0;
+    var stackTop = 0;
+    var root = 1;
+
+    stackNodes[0] = root;
+
+    var stream = new _ReadStream(_chunks);
+    stream.position = positions[root];
+    stream.readUnsigned(); // addr
+    stream.readUnsigned(); // shallowSize
+    stream.readUnsigned(); // cid
+    stackCurrentEdgePos[0] = stream.position;
+    visited[root] = 1;
+
+    while (stackTop >= 0) {
+      var n = stackNodes[stackTop];
+      var edgePos = stackCurrentEdgePos[stackTop];
+
+      stream.position = edgePos;
+      var childAddr = stream.readUnsigned();
+      if (childAddr != 0) {
+        stackCurrentEdgePos[stackTop] = stream.position;
+        var childId = addrToId[childAddr];
+        if (childId == null) continue; // Reference to VM isolate's heap.
+        E++;
+        if (visited[childId] == 1) continue;
+
+        stackTop++;
+        stackNodes[stackTop] = childId;
+
+        stream.position = positions[childId];
+        stream.readUnsigned(); // addr
+        stream.readUnsigned(); // shallowSize
+        stream.readUnsigned(); // cid
+        stackCurrentEdgePos[stackTop] = stream.position; // i.e., first edge
+        visited[childId] = 1;
+      } else {
+        // Done with all children.
+        postOrderIndices[n] = postOrderIndex;
+        postOrderOrdinals[postOrderIndex++] = n;
+        stackTop--;
+      }
+    }
+
+    assert(postOrderIndex == N);
+    assert(postOrderOrdinals[N - 1] == root);
+
+    _postOrderOrdinals = postOrderOrdinals;
+    _postOrderIndices = postOrderIndices;
+    _E = E;
+  }
+
+  void _buildPredecessors() {
+    var N = _N;
+    var E = _E;
+    var addrToId = _addrToId;
+    var positions = _positions;
+
+    // This is first filled with the predecessor counts, then reused to hold the
+    // offset to the first predecessor (see alias below).
+    // + 1 because 0 is a sentinel
+    // + 1 so the number of predecessors can be found from the difference with
+    // the next node's offset.
+    var numPreds = new Uint32List(N + 2);
+    var preds = new Uint32List(E);
+
+    // Count predecessors of each node.
+    var stream = new _ReadStream(_chunks);
+    for (var i = 1; i <= N; i++) {
+      stream.position = positions[i];
+      stream.readUnsigned(); // addr
+      stream.readUnsigned(); // shallowSize
+      stream.readUnsigned(); // cid
+      var succAddr = stream.readUnsigned();
+      while (succAddr != 0) {
+        var succId = addrToId[succAddr];
+        if (succId != null) {
+          numPreds[succId]++;
+        } else {
+          // Reference to VM isolate's heap.
+        }
+        succAddr = stream.readUnsigned();
+      }
+    }
+
+    // Assign indices into predecessors array.
+    var firstPreds = numPreds;  // Alias.
+    var nextPreds = new Uint32List(N + 1);
+    var predIndex = 0;
+    for (var i = 1; i <= N; i++) {
+      var thisPredIndex = predIndex;
+      predIndex += numPreds[i];
+      firstPreds[i] = thisPredIndex;
+      nextPreds[i] = thisPredIndex;
+    }
+    assert(predIndex == E);
+    firstPreds[N + 1] = E; // Extra entry for cheap boundary detection.
+
+    // Fill predecessors array.
+    for (var i = 1; i <= N; i++) {
+      stream.position = positions[i];
+      stream.readUnsigned(); // addr
+      stream.readUnsigned(); // shallowSize
+      stream.readUnsigned(); // cid
+      var succAddr = stream.readUnsigned();
+      while (succAddr != 0) {
+        var succId = addrToId[succAddr];
+        if (succId != null) {
+          var predIndex = nextPreds[succId]++;
+          preds[predIndex] = i;
+        } else {
+          // Reference to VM isolate's heap.
+        }
+        succAddr = stream.readUnsigned();
+      }
+    }
+
+    _firstPreds = firstPreds;
+    _preds = preds;
+  }
+
+  // "A Simple, Fast Dominance Algorithm"
+  // Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy
+  void _buildDominators() {
+    var N = _N;
+    var E = _E;
+    var addrToId = _addrToId;
+    var postOrder = _postOrderOrdinals;
+    var postOrderIndex = _postOrderIndices;
+    var firstPreds = _firstPreds;
+    var preds = _preds;
+
+    var root = 1;
+    var rootPostOrderIndex = postOrderIndex[root];
+    var domByPOI = new Uint32List(N + 1);
+
+    domByPOI[rootPostOrderIndex] = rootPostOrderIndex;
+
+    var iteration = 0;
+    var changed = true;
+    while (changed) {
+      changed = false;
+      Logger.root.info("Find dominators iteration $iteration");
+      iteration++; // dart2js heaps typically converge in 10 iterations.
+
+      // Visit the nodes, except the root, in reverse post order (top down).
+      for (var curPostOrderIndex = rootPostOrderIndex - 1;
+           curPostOrderIndex > 1;
+           curPostOrderIndex--) {
+        if (domByPOI[curPostOrderIndex] == rootPostOrderIndex)
+          continue;
+
+        var nodeOrdinal = postOrder[curPostOrderIndex];
+        var newDomIndex = 0; // 0 = undefined
+
+        // Intersect the DOM sets of the node's precedessors.
+        var beginPredIndex = firstPreds[nodeOrdinal];
+        var endPredIndex = firstPreds[nodeOrdinal + 1];
+        for (var predIndex = beginPredIndex;
+             predIndex < endPredIndex;
+             predIndex++) {
+          var predOrdinal = preds[predIndex];
+          var predPostOrderIndex = postOrderIndex[predOrdinal];
+          if (domByPOI[predPostOrderIndex] != 0) {
+            if (newDomIndex == 0) {
+              newDomIndex = predPostOrderIndex;
+            } else {
+              // Note this two finger algorithm to find the DOM intersection
+              // relies on comparing nodes by their post order index.
+              while (predPostOrderIndex != newDomIndex) {
+                while(predPostOrderIndex < newDomIndex)
+                  predPostOrderIndex = domByPOI[predPostOrderIndex];
+                while (newDomIndex < predPostOrderIndex)
+                  newDomIndex = domByPOI[newDomIndex];
+              }
+            }
+            if (newDomIndex == rootPostOrderIndex) {
+              break;
+            }
+          }
+        }
+        if (newDomIndex != 0 && domByPOI[curPostOrderIndex] != newDomIndex) {
+          domByPOI[curPostOrderIndex] = newDomIndex;
+          changed = true;
+        }
+      }
+    }
+
+    // Reindex doms by id instead of post order index so we can throw away
+    // the post order arrays.
+    var domById = new Uint32List(N + 1);
+    for (var id = 1; id <= N; id++) {
+      domById[id] = postOrder[domByPOI[postOrderIndex[id]]];
+    }
+
+    domById[root] = 0;
+
+    _doms = domById;
+  }
+
+  void _calculateRetainedSizes() {
+    var N = _N;
+    var E = _E;
+
+    var size = 0;
+    var positions = _positions;
+    var postOrderOrdinals = _postOrderOrdinals;
+    var doms = _doms;
+    var retainedSizes = new Uint32List(N + 1);
+
+    // Start with retained size as shallow size.
+    var reader = new _ReadStream(_chunks);
+    for (var i = 1; i <= N; i++) {
+      reader.position = positions[i];
+      reader.readUnsigned(); // addr
+      var shallowSize = reader.readUnsigned();
+      retainedSizes[i] = shallowSize;
+      size += shallowSize;
+    }
+
+    // In post order (bottom up), add retained size to dominator's retained
+    // size, skipping root.
+    for (var o = 0; o < (N - 1); o++) {
+      var i = postOrderOrdinals[o];
+      assert(i != 1);
+      retainedSizes[doms[i]] += retainedSizes[i];
+    }
+
+    _retainedSizes = retainedSizes;
+    _size = size;
+  }
+}
diff --git a/runtime/observatory/lib/src/app/application.dart b/runtime/observatory/lib/src/app/application.dart
index ef74096..ef8d574 100644
--- a/runtime/observatory/lib/src/app/application.dart
+++ b/runtime/observatory/lib/src/app/application.dart
@@ -131,6 +131,7 @@
     _pageRegistry.add(new TableCpuProfilerPage(this));
     _pageRegistry.add(new AllocationProfilerPage(this));
     _pageRegistry.add(new HeapMapPage(this));
+    _pageRegistry.add(new HeapSnapshotPage(this));
     _pageRegistry.add(new VMConnectPage(this));
     _pageRegistry.add(new IsolateReconnectPage(this));
     _pageRegistry.add(new ErrorViewPage(this));
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index 275ecb0..1151f67 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -265,6 +265,21 @@
   }
 }
 
+class HeapSnapshotPage extends SimplePage {
+  HeapSnapshotPage(app) : super('heap-snapshot', 'heap-snapshot', app);
+
+  void _visit(Uri uri) {
+    super._visit(uri);
+    getIsolate(uri).then((isolate) {
+      if (element != null) {
+        /// Update the page.
+        HeapSnapshotElement page = element;
+        page.isolate = isolate;
+      }
+    });
+  }
+}
+
 class ErrorViewPage extends Page {
   ErrorViewPage(app) : super(app);
 
diff --git a/runtime/observatory/lib/src/elements/class_view.dart b/runtime/observatory/lib/src/elements/class_view.dart
index b9920c0..25cb6cb 100644
--- a/runtime/observatory/lib/src/elements/class_view.dart
+++ b/runtime/observatory/lib/src/elements/class_view.dart
@@ -28,7 +28,7 @@
   }
 
   Future<ServiceObject> retainedToplist(var limit) {
-    return cls.isolate.fetchHeapSnapshot()
+    return cls.isolate.fetchHeapSnapshot().last
       .then((HeapSnapshot snapshot) =>
           Future.wait(snapshot.getMostRetained(classId: cls.vmCid,
                                                limit: 10)))
diff --git a/runtime/observatory/lib/src/elements/code_view.dart b/runtime/observatory/lib/src/elements/code_view.dart
index 868886f..4995996 100644
--- a/runtime/observatory/lib/src/elements/code_view.dart
+++ b/runtime/observatory/lib/src/elements/code_view.dart
@@ -67,7 +67,7 @@
 
   Future refreshTicks() {
     var isolate = code.isolate;
-    return isolate.invokeRpc('getCpuProfile', { 'tags': 'None' })
+    return isolate.invokeRpc('_getCpuProfile', { 'tags': 'None' })
         .then((ServiceMap response) {
             var cpuProfile = new CpuProfile();
             cpuProfile.load(isolate, response);
diff --git a/runtime/observatory/lib/src/elements/cpu_profile.dart b/runtime/observatory/lib/src/elements/cpu_profile.dart
index 13e7c21..3fc31a2 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile.dart
@@ -485,7 +485,7 @@
     if (isolate == null) {
       return new Future.value(null);
     }
-    return isolate.invokeRpc('clearCpuProfile', { })
+    return isolate.invokeRpc('_clearCpuProfile', { })
         .then((ServiceMap response) {
           _updateView();
         });
@@ -535,7 +535,7 @@
     _onFetchStarted();
     try {
       var params = { 'tags': tagSelector };
-      var response = await isolate.invokeRpc('getCpuProfile', params);
+      var response = await isolate.invokeRpc('_getCpuProfile', params);
       _onFetchFinished();
       await _onLoadStarted();
       profile.load(isolate, response);
@@ -850,7 +850,7 @@
     if (isolate == null) {
       return new Future.value(null);
     }
-    return isolate.invokeRpc('clearCpuProfile', { })
+    return isolate.invokeRpc('_clearCpuProfile', { })
     .then((ServiceMap response) {
       _updateView();
     });
@@ -865,7 +865,7 @@
     _onFetchStarted();
     try {
       var params = { 'tags': 'None' };
-      var response = await isolate.invokeRpc('getCpuProfile', params);
+      var response = await isolate.invokeRpc('_getCpuProfile', params);
       _onFetchFinished();
       _onLoadStarted();
       profile.load(isolate, response);
diff --git a/runtime/observatory/lib/src/elements/heap_map.dart b/runtime/observatory/lib/src/elements/heap_map.dart
index 631b780..7b7be4f 100644
--- a/runtime/observatory/lib/src/elements/heap_map.dart
+++ b/runtime/observatory/lib/src/elements/heap_map.dart
@@ -224,7 +224,7 @@
       fragmentation = null;
       return;
     }
-    isolate.invokeRpc('getHeapMap', {}).then((ServiceMap response) {
+    isolate.invokeRpc('_getHeapMap', {}).then((ServiceMap response) {
       assert(response['type'] == 'HeapMap');
       fragmentation = response;
     }).catchError((e, st) {
@@ -236,7 +236,7 @@
     if (isolate == null) {
       return new Future.value(null);
     }
-    return isolate.invokeRpc('getHeapMap', {}).then((ServiceMap response) {
+    return isolate.invokeRpc('_getHeapMap', {}).then((ServiceMap response) {
       assert(response['type'] == 'HeapMap');
       fragmentation = response;
     });
diff --git a/runtime/observatory/lib/src/elements/heap_profile.dart b/runtime/observatory/lib/src/elements/heap_profile.dart
index 5e097e5..01c3608 100644
--- a/runtime/observatory/lib/src/elements/heap_profile.dart
+++ b/runtime/observatory/lib/src/elements/heap_profile.dart
@@ -26,7 +26,6 @@
   }
 }
 
-/// Displays an Error response.
 @CustomTag('heap-profile')
 class HeapProfileElement extends ObservatoryElement {
   @observable String lastServiceGC = '---';
@@ -103,11 +102,11 @@
     _subscription.cancel();
     super.detached();
   }
-  
+
   // Keep at most one outstanding auto-refresh RPC.
   bool refreshAutoPending = false;
   bool refreshAutoQueued = false;
-  
+
   void _onEvent(ServiceEvent event) {
     if (autoRefresh && event.eventType == 'GC') {
       if (!refreshAutoPending) {
@@ -232,6 +231,9 @@
       var cell = tr.children[i];
       cell.title = row.values[i].toString();
       cell.text = classTable.getFormattedValue(rowIndex, i);
+      if (i > 1) {  // Numbers.
+        cell.style.textAlign = 'right';
+      }
     }
   }
 
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart
new file mode 100644
index 0000000..4285692
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart
@@ -0,0 +1,463 @@
+// 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 heap_snapshot_element;
+
+import 'dart:async';
+import 'dart:html';
+import 'observatory_element.dart';
+import 'heap_profile.dart';
+import 'package:observatory/app.dart';
+import 'package:observatory/service.dart';
+import 'package:observatory/elements.dart';
+import 'package:observatory/object_graph.dart';
+import 'package:logging/logging.dart';
+import 'package:polymer/polymer.dart';
+
+class DominatorTreeRow extends TableTreeRow {
+  final ObjectVertex vertex;
+  final HeapSnapshot snapshot;
+
+  var _domTreeChildren;
+  get domTreeChildren {
+    if (_domTreeChildren == null) {
+      _domTreeChildren = vertex.dominatorTreeChildren();
+    }
+    return _domTreeChildren;
+  }
+
+  DominatorTreeRow(TableTree tree,
+                   TableTreeRow parent,
+                   this.vertex,
+                   this.snapshot)
+      : super(tree, parent) {
+  }
+
+  bool hasChildren() {
+    return domTreeChildren.length > 0;
+  }
+
+  static const int kMaxChildren = 100;
+  static const int kMinRetainedSize = 4096;
+
+  void onShow() {
+    super.onShow();
+    if (children.length == 0) {
+      domTreeChildren.sort((a, b) => b.retainedSize - a.retainedSize);
+      int includedChildren = 0;
+      for (var childVertex in domTreeChildren) {
+        if (childVertex.retainedSize >= kMinRetainedSize) {
+          if (++includedChildren <= kMaxChildren) {
+            var row = new DominatorTreeRow(tree, this, childVertex, snapshot);
+            children.add(row);
+          }
+        }
+      }
+    }
+
+    var firstColumn = flexColumns[0];
+    firstColumn.style.justifyContent = 'flex-start';
+    firstColumn.style.position = 'relative';
+    firstColumn.style.alignItems = 'center';
+    firstColumn.style.setProperty('overflow-x', 'hidden');
+
+    var percentRetained = vertex.retainedSize / snapshot.graph.size;
+    var percentNode = new SpanElement();
+    percentNode.text =  Utils.formatPercentNormalized(percentRetained);
+    percentNode.style.minWidth = '5em';
+    percentNode.style.textAlign = 'right';
+    percentNode.title = "Retaining x of y.";
+    percentNode.style.display = 'inline-block';
+    firstColumn.children.add(percentNode);
+
+    var gap = new SpanElement();
+    gap.style.minWidth = '1em';
+    gap.style.display = 'inline-block';
+    firstColumn.children.add(gap);
+
+    AnyServiceRefElement objectRef = new Element.tag("any-service-ref");
+    String hexAddress = vertex.address.toRadixString(16);
+    snapshot.isolate.getObjectByAddress(hexAddress).then((obj) {
+      objectRef.ref = obj;
+    });
+    objectRef.style.alignSelf = 'center';
+    firstColumn.children.add(objectRef);
+
+    var secondColumn = flexColumns[1];
+    secondColumn.style.justifyContent = 'flex-end';
+    secondColumn.style.position = 'relative';
+    secondColumn.style.alignItems = 'center';
+    secondColumn.style.paddingRight = '0.5em';
+    secondColumn.text = Utils.formatSize(vertex.retainedSize);
+  }
+}
+
+
+class MergedVerticesRow extends TableTreeRow {
+  final Isolate isolate;
+  final List<MergedVertex> mergedVertices;
+
+  MergedVerticesRow(TableTree tree,
+                   TableTreeRow parent,
+                   this.isolate,
+                   this.mergedVertices)
+      : super(tree, parent) {
+  }
+
+  bool hasChildren() {
+    return mergedVertices.length > 0;
+  }
+
+  void onShow() {
+    super.onShow();
+
+    if (children.length == 0) {
+      mergedVertices.sort((a, b) => b.shallowSize - a.shallowSize);
+      for (var mergedVertex in mergedVertices) {
+        if (mergedVertex.instances > 0) {
+          var row = new MergedVertexRow(tree, this, isolate, mergedVertex);
+          children.add(row);
+        }
+      }
+    }
+  }
+}
+
+class MergedVertexRow extends TableTreeRow {
+  final Isolate isolate;
+  final MergedVertex vertex;
+
+  MergedVertexRow(TableTree tree,
+                  TableTreeRow parent,
+                  this.isolate,
+                  this.vertex)
+      : super(tree, parent) {
+  }
+
+  bool hasChildren() {
+    return vertex.outgoingEdges.length > 0 ||
+           vertex.incomingEdges.length > 0;
+  }
+
+  void onShow() {
+    super.onShow();
+    if (children.length == 0) {
+      children.add(new MergedEdgesRow(tree, this, isolate, vertex, true));
+      children.add(new MergedEdgesRow(tree, this, isolate, vertex, false));
+    }
+
+
+    var firstColumn = flexColumns[0];
+    firstColumn.style.justifyContent = 'flex-start';
+    firstColumn.style.position = 'relative';
+    firstColumn.style.alignItems = 'center';
+
+    var percentNode = new SpanElement();
+    percentNode.text = "${vertex.instances} instances of";
+    percentNode.style.minWidth = '5em';
+    percentNode.style.textAlign = 'right';
+    firstColumn.children.add(percentNode);
+
+    var gap = new SpanElement();
+    gap.style.minWidth = '1em';
+    gap.style.display = 'inline-block';
+    firstColumn.children.add(gap);
+
+    ClassRefElement classRef = new Element.tag("class-ref");
+    classRef.ref = isolate.getClassByCid(vertex.cid);
+    classRef.style.alignSelf = 'center';
+    firstColumn.children.add(classRef);
+
+    var secondColumn = flexColumns[1];
+    secondColumn.style.justifyContent = 'flex-end';
+    secondColumn.style.position = 'relative';
+    secondColumn.style.alignItems = 'center';
+    secondColumn.style.paddingRight = '0.5em';
+    secondColumn.text = Utils.formatSize(vertex.shallowSize);
+  }
+}
+
+class MergedEdgesRow extends TableTreeRow {
+  final Isolate isolate;
+  final MergedVertex vertex;
+  final bool outgoing;
+
+  MergedEdgesRow(TableTree tree,
+                 TableTreeRow parent,
+                 this.isolate,
+                 this.vertex,
+                 this.outgoing)
+      : super(tree, parent) {
+  }
+
+  bool hasChildren() {
+    return outgoing
+            ? vertex.outgoingEdges.length > 0
+            : vertex.incomingEdges.length > 0;
+  }
+
+  void onShow() {
+    super.onShow();
+    if (children.length == 0) {
+      if (outgoing) {
+        var outgoingEdges = vertex.outgoingEdges.values.toList();
+        outgoingEdges.sort((a, b) => b.shallowSize - a.shallowSize);
+        for (var edge in outgoingEdges) {
+          if (edge.count > 0) {
+            var row = new MergedEdgeRow(tree, this, isolate, edge, true);
+            children.add(row);
+          }
+        }
+      } else {
+        vertex.incomingEdges.sort((a, b) => b.shallowSize - a.shallowSize);
+        for (var edge in vertex.incomingEdges) {
+          if (edge.count > 0) {
+            var row = new MergedEdgeRow(tree, this, isolate, edge, false);
+            children.add(row);
+          }
+        }
+      }
+    }
+
+    var count = 0;
+    var shallowSize = 0;
+    var edges = outgoing ? vertex.outgoingEdges.values : vertex.incomingEdges;
+    for (var edge in edges) {
+      count += edge.count;
+      shallowSize += edge.shallowSize;
+    }
+
+    var firstColumn = flexColumns[0];
+    firstColumn.style.justifyContent = 'flex-start';
+    firstColumn.style.position = 'relative';
+    firstColumn.style.alignItems = 'center';
+
+    var countNode = new SpanElement();
+    countNode.text = "$count";
+    countNode.style.minWidth = '5em';
+    countNode.style.textAlign = 'right';
+    firstColumn.children.add(countNode);
+
+    var gap = new SpanElement();
+    gap.style.minWidth = '1em';
+    gap.style.display = 'inline-block';
+    firstColumn.children.add(gap);
+
+    var labelNode = new SpanElement();
+    labelNode.text = outgoing ? "Outgoing references" : "Incoming references";
+    firstColumn.children.add(labelNode);
+
+    var secondColumn = flexColumns[1];
+    secondColumn.style.justifyContent = 'flex-end';
+    secondColumn.style.position = 'relative';
+    secondColumn.style.alignItems = 'center';
+    secondColumn.style.paddingRight = '0.5em';
+    secondColumn.text = Utils.formatSize(shallowSize);
+  }
+}
+
+class MergedEdgeRow extends TableTreeRow {
+  final Isolate isolate;
+  final MergedEdge edge;
+  final bool outgoing;
+
+  MergedEdgeRow(TableTree tree,
+                TableTreeRow parent,
+                this.isolate,
+                this.edge,
+                this.outgoing)
+      : super(tree, parent) {
+  }
+
+  bool hasChildren() => false;
+
+  void onShow() {
+    super.onShow();
+
+    var firstColumn = flexColumns[0];
+    firstColumn.style.justifyContent = 'flex-start';
+    firstColumn.style.position = 'relative';
+    firstColumn.style.alignItems = 'center';
+
+    var percentNode = new SpanElement();
+    var preposition = outgoing ? "to" : "from";
+    percentNode.text = "${edge.count} references $preposition instances of";
+    percentNode.style.minWidth = '5em';
+    percentNode.style.textAlign = 'right';
+    firstColumn.children.add(percentNode);
+
+    var gap = new SpanElement();
+    gap.style.minWidth = '1em';
+    gap.style.display = 'inline-block';
+    firstColumn.children.add(gap);
+
+    MergedVertex v = outgoing ? edge.target : edge.source;
+    if (v.cid == 0) {
+      var rootName = new SpanElement();
+      rootName.text = '<root>';
+      firstColumn.children.add(rootName);
+    } else {
+      ClassRefElement classRef = new Element.tag("class-ref");
+      classRef.ref = isolate.getClassByCid(v.cid);
+      classRef.style.alignSelf = 'center';
+      firstColumn.children.add(classRef);
+    }
+
+    var secondColumn = flexColumns[1];
+    secondColumn.style.justifyContent = 'flex-end';
+    secondColumn.style.position = 'relative';
+    secondColumn.style.alignItems = 'center';
+    secondColumn.style.paddingRight = '0.5em';
+    secondColumn.text = Utils.formatSize(edge.shallowSize);
+  }
+}
+
+
+class MergedEdge {
+  final MergedVertex source;
+  final MergedVertex target;
+  int count = 0;
+  int shallowSize = 0;
+  int retainedSize = 0;
+
+  MergedEdge(this.source, this.target);
+}
+
+class MergedVertex {
+  final int cid;
+  int instances = 0;
+  int shallowSize = 0;
+  int retainedSize = 0;
+
+  List<MergedEdge> incomingEdges = new List<MergedEdge>();
+  Map<int, MergedEdge> outgoingEdges = new Map<int, MergedEdge>();
+
+  MergedVertex(this.cid);
+}
+
+
+Future<List<MergedVertex>> buildMergedVertices(ObjectGraph graph) async {
+  var cidToMergedVertex = {};
+
+  for (var vertex in graph.vertices) {
+    var cid = vertex.vmCid;
+    MergedVertex source = cidToMergedVertex[cid];
+    if (source == null) {
+      cidToMergedVertex[cid] = source = new MergedVertex(cid);
+    }
+
+    source.instances++;
+    source.shallowSize += (vertex.shallowSize == null ? 0 : vertex.shallowSize);
+
+    for (var vertex2 in vertex.successors) {
+      var cid2 = vertex2.vmCid;
+      MergedEdge edge = source.outgoingEdges[cid2];
+      if (edge == null) {
+        MergedVertex target = cidToMergedVertex[cid2];
+        if (target == null) {
+          cidToMergedVertex[cid2] = target = new MergedVertex(cid2);
+        }
+        edge = new MergedEdge(source, target);
+        source.outgoingEdges[cid2] = edge;
+        target.incomingEdges.add(edge);
+      }
+      edge.count++;
+      // An over-estimate if there are multiple references to the same object.
+      edge.shallowSize += vertex2.shallowSize == null ? 0 : vertex2.shallowSize;
+    }
+  }
+
+  return cidToMergedVertex.values.toList();
+}
+
+@CustomTag('heap-snapshot')
+class HeapSnapshotElement extends ObservatoryElement {
+  @published Isolate isolate;
+  @observable HeapSnapshot snapshot;
+
+  @published String state = 'Requested';
+  @published String analysisSelector = 'DominatorTree';
+
+  HeapSnapshotElement.created() : super.created();
+
+  void analysisSelectorChanged(oldValue) {
+    _update();
+  }
+
+  void isolateChanged(oldValue) {
+    if (isolate == null) return;
+
+    if (isolate.latestSnapshot == null) {
+      _getHeapSnapshot();
+    } else {
+      snapshot = isolate.latestSnapshot;
+      state = 'Loaded';
+      _update();
+    }
+  }
+
+  Future refresh() {
+    return _getHeapSnapshot();
+  }
+
+  Future _getHeapSnapshot() {
+    var completer = new Completer();
+    state = "Requesting heap snapshot...";
+    isolate.getClassRefs();
+    var stopwatch = new Stopwatch()..start();
+    isolate.fetchHeapSnapshot().listen((event) {
+      if (event is String) {
+        print("${stopwatch.elapsedMilliseconds} $event");
+        state = event;
+      } else if (event is HeapSnapshot) {
+        snapshot = event;
+        state = 'Loaded';
+        completer.complete(snapshot);
+        _update();
+      } else {
+        throw "Unexpected event $event";
+      }
+    });
+    return completer.future;
+  }
+
+  void _update() {
+    if (snapshot == null) {
+      return;
+    }
+
+    switch(analysisSelector) {
+    case 'DominatorTree':
+      _buildDominatorTree();
+      break;
+    case 'MergeByClass':
+      _buildMergedVertices();
+      break;
+    }
+  }
+
+  void _buildDominatorTree() {
+    var tableBody = shadowRoot.querySelector('#treeBody');
+    var tree = new TableTree(tableBody, 2);
+    var rootRow =
+        new DominatorTreeRow(tree, null, snapshot.graph.root, snapshot);
+    tree.initialize(rootRow);
+    return;
+  }
+
+  void _buildMergedVertices() {
+    state = 'Grouping...';
+    var tableBody = shadowRoot.querySelector('#treeBody');
+    var tree = new TableTree(tableBody, 2);
+    tableBody.children.clear();
+
+    new Future.delayed(const Duration(milliseconds: 500), () {
+      buildMergedVertices(snapshot.graph).then((vertices) {
+        state = 'Loaded';
+        var rootRow = new MergedVerticesRow(tree, null, isolate, vertices);
+        tree.initialize(rootRow);
+      });
+    });
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.html b/runtime/observatory/lib/src/elements/heap_snapshot.html
new file mode 100644
index 0000000..d593f97
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.html
@@ -0,0 +1,201 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="class_ref.html">
+<link rel="import" href="observatory_element.html">
+<link rel="import" href="nav_bar.html">
+<link rel="import" href="view_footer.html">
+
+<polymer-element name="heap-snapshot" extends="observatory-element">
+<template>
+  <link rel="stylesheet" href="css/shared.css">
+  <nav-bar>
+    <top-nav-menu></top-nav-menu>
+    <vm-nav-menu vm="{{ isolate.vm }}"></vm-nav-menu>
+    <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
+    <nav-menu link="{{ makeLink('/heap-snapshot', isolate) }}" anchor="heap snapshot" last="{{ true }}"></nav-menu>
+    <nav-refresh callback="{{ refresh }}"></nav-refresh>
+  </nav-bar>
+  <style>
+      /* general */
+      .well {
+        background-color: #ECECEC;
+        padding: 0.2em;
+      }
+      .center {
+        align-items: center;
+        justify-content: center;
+      }
+
+      /* status messages */
+      .statusMessage {
+        font-size: 150%;
+        font-weight: bold;
+      }
+      .statusBox {
+        height: 100%;
+        padding: 1em;
+      }
+
+      /* tables */
+      .table {
+        border-collapse: collapse!important;
+        table-layout: fixed;
+        height: 100%;
+      }
+      .th, .td {
+        padding: 8px;
+        vertical-align: top;
+      }
+      .table thead > tr > th {
+        vertical-align: bottom;
+        text-align: left;
+        border-bottom:2px solid #ddd;
+      }
+      .spacer {
+        width: 16px;
+      }
+      .left-border-spacer {
+        width: 16px;
+        border-left: 1px solid;
+      }
+      .clickable {
+        color: #0489c3;
+        text-decoration: none;
+        cursor: pointer;
+        min-width: 8em;
+      }
+      .clickable:hover {
+        text-decoration: underline;
+        cursor: pointer;
+      }
+      tr:hover:not(.focused) > td {
+        background-color: #FAFAFA;
+      }
+      .focused {
+        background-color: #F4C7C3;
+      }
+      .scroll {
+        overflow: scroll;
+      }
+      .outlined {
+        -webkit-box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
+        -moz-box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
+        box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
+        margin: 4px;
+      }
+      .centered {
+        margin-left: auto;
+        margin-right: auto;
+        justify-content: center;
+      }
+      .full-height {
+        height: 100%;
+      }
+      .mostly-full-height {
+        height: 80%;
+      }
+      .full-width {
+        width: 100%;
+      }
+      .focused-function-label {
+        flex: 0 1 auto;
+        margin-left: auto;
+        margin-right: auto;
+        justify-content: center;
+      }
+      .call-table {
+        flex: 1 1 auto;
+      }
+
+      .tree {
+        border-spacing: 0px;
+        width: 100%;
+        margin-bottom: 20px
+        vertical-align: middle;
+      }
+
+      .tree tbody tr {
+        animation: fadeIn 0.5s;
+        -moz-animation: fadeIn 0.5s;
+        -webkit-animation: fadeIn 0.5s;
+      }
+
+      .tree tbody tr:hover {
+        background-color: #FAFAFA;
+      }
+
+      .tree tr td:first-child,
+      .tree tr th:first-child {
+        width: 100%;
+      }
+
+      .tree thead > tr > th {
+        padding: 8px;
+        vertical-align: bottom;
+        text-align: left;
+        border-bottom: 1px solid #ddd;
+      }
+  </style>
+  <div class="content-centered-big">
+    <h1>Heap Snapshot (Experimental)</h1>
+    <hr>
+    <template if="{{ state != 'Loaded' }}">
+      <div class="statusBox shadow center">
+        <div class="statusMessage">{{state}}</div>
+      </div>
+    </template>
+    <template if="{{ state == 'Loaded' }}">
+      <div class="memberList">
+        <div class="memberItem">
+          <div class="memberName">Refreshed at </div>
+          <div class="memberValue">{{ snapshot.timeStamp }}</div>
+        </div>
+        <div class="memberItem">
+          <div class="memberName">Objects </div>
+          <div class="memberValue">{{ snapshot.graph.vertexCount }}</div>
+        </div>
+        <div class="memberItem">
+          <div class="memberName">References </div>
+          <div class="memberValue">{{ snapshot.graph.edgeCount }}</div>
+        </div>
+        <div class="memberItem">
+          <div class="memberName">Size </div>
+          <div class="memberValue">{{ snapshot.graph.size | formatSize }}</div>
+        </div>
+        <div class="memberItem">
+           <div class="memberName">Analysis </div>
+           <div class="memberValue">
+             <select value="{{analysisSelector}}">
+               <option value="DominatorTree">Dominator tree</option>
+               <option value="MergeByClass">Group by class</option>
+             </select>
+           </div>
+        </div>
+      </div>
+      <template if="{{analysisSelector == 'DominatorTree'}}"><p>In a heap dominator tree, an object X is a parent of object Y if every path from the root to Y goes through X. This allows you to find "choke points" that are holding onto a lot memory. If an object becomes garbage, all its children in the dominator tree become garbage as well. The retained size of an object is the sum of the retained sizes of its children in the dominator tree plus its own shallow size, and is the amount of memory that would be freed if the object became garbage.</p></template>
+    </template>
+  </div>
+  <br>
+  <div class="content-centered-big">
+    <div class="tableWell shadow">
+      <table class="full-width tree">
+        <thead id="treeHeader">
+        <tr>
+          <th>
+            <template if="{{analysisSelector == 'DominatorTree'}}">Object</template>
+            <template if="{{analysisSelector == 'MergeByClass'}}">Class</template>
+          </th>
+          <th style="white-space: nowrap">
+            <template if="{{analysisSelector == 'DominatorTree'}}">Retained Size</template>
+            <template if="{{analysisSelector == 'MergeByClass'}}">Shallow Size</template>
+          </th>
+        </tr>
+        </thead>
+          <tbody id="treeBody"></tbody>
+      </table>
+    </div>
+  </div>
+  <view-footer></view-footer>
+</template>
+</polymer-element>
+
+<script type="application/dart" src="heap_snapshot.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/instance_ref.html b/runtime/observatory/lib/src/elements/instance_ref.html
index 8543b50..6b1ee82 100644
--- a/runtime/observatory/lib/src/elements/instance_ref.html
+++ b/runtime/observatory/lib/src/elements/instance_ref.html
@@ -38,7 +38,7 @@
 
       <template if="{{ ref.isClosure }}">
         <a on-click="{{ goto }}" _href="{{ url }}">
-          {{ ref.closureFunc.qualifiedName }}
+          {{ ref.function.qualifiedName }}
         </a>
       </template>
 
diff --git a/runtime/observatory/lib/src/elements/instance_view.html b/runtime/observatory/lib/src/elements/instance_view.html
index 686cec8..517cc2d 100644
--- a/runtime/observatory/lib/src/elements/instance_view.html
+++ b/runtime/observatory/lib/src/elements/instance_view.html
@@ -84,7 +84,7 @@
             <div class="memberItem">
               <div class="memberName">closure function</div>
               <div class="memberValue">
-                <function-ref ref="{{ instance.closureFunc }}">
+                <function-ref ref="{{ instance.function }}">
                 </function-ref>
               </div>
             </div>
@@ -93,7 +93,7 @@
             <div class="memberItem">
               <div class="memberName">closure context</div>
               <div class="memberValue">
-                <any-service-ref ref="{{ instance.closureCtxt }}">
+                <any-service-ref ref="{{ instance.context }}">
                 </any-service-ref>
               </div>
             </div>
diff --git a/runtime/observatory/lib/src/elements/isolate_summary.html b/runtime/observatory/lib/src/elements/isolate_summary.html
index 054d3f6..54817b1 100644
--- a/runtime/observatory/lib/src/elements/isolate_summary.html
+++ b/runtime/observatory/lib/src/elements/isolate_summary.html
@@ -182,6 +182,11 @@
             See <a on-click="{{ goto }}" _href="{{ gotoLink('/metrics', isolate) }}">metrics</a>
           </div>
         </div>
+        <div class="memberItem">
+          <div class="memberValue">
+            See <a on-click="{{ goto }}" _href="{{ gotoLink('/heap-snapshot', isolate) }}">heap snapshot</a>
+          </div>
+        </div>
         <!-- Temporarily disabled until UI for dart:io is acceptable.
         <template if="{{ isolate.ioEnabled }}">
           <div class="memberItem">
diff --git a/runtime/observatory/lib/src/elements/library_view.html b/runtime/observatory/lib/src/elements/library_view.html
index 32b4d2d..65db44c 100644
--- a/runtime/observatory/lib/src/elements/library_view.html
+++ b/runtime/observatory/lib/src/elements/library_view.html
@@ -31,8 +31,8 @@
       </h1>
       <div class="memberList">
         <div class="memberItem">
-          <div class="memberName">url</div>
-          <div class="memberValue">{{ library.url }}</div>
+          <div class="memberName">uri</div>
+          <div class="memberValue">{{ library.uri }}</div>
         </div>
         <template if="{{ library.name != library.vmName }}">
           <div class="memberItem">
diff --git a/runtime/observatory/lib/src/elements/service_view.html b/runtime/observatory/lib/src/elements/service_view.html
index 2c4213b..723248f 100644
--- a/runtime/observatory/lib/src/elements/service_view.html
+++ b/runtime/observatory/lib/src/elements/service_view.html
@@ -10,6 +10,7 @@
 <link rel="import" href="heap_profile.html">
 <link rel="import" href="instance_view.html">
 <link rel="import" href="library_view.html">
+<link rel="import" href="heap_snapshot.html">
 <link rel="import" href="observatory_element.html">
 <link rel="import" href="script_view.html">
 <link rel="import" href="vm_view.html">
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 98a128b..d2c9703 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -281,10 +281,13 @@
   Future<ServiceObject> reload() {
     // TODO(turnidge): Checking for a null id should be part of the
     // "immmutable" check.
-    if (id == null || id == '') {
-      return new Future.value(this);
-    }
-    if (loaded && immutable) {
+    bool hasId = (id != null) && (id != '');
+    bool isVM = this is VM;
+    // We should always reload the VM.
+    // We can't reload objects without an id.
+    // We shouldn't reload an immutable and already loaded object.
+    bool skipLoad = !isVM && (!hasId || (immutable && loaded));
+    if (skipLoad) {
       return new Future.value(this);
     }
     if (_inProgressReload == null) {
@@ -779,10 +782,9 @@
   final DateTime timeStamp;
   final Isolate isolate;
 
-  HeapSnapshot(this.isolate, ByteData data) :
-      graph = new ObjectGraph(new ReadStream(data)),
-      timeStamp = new DateTime.now() {
-  }
+  HeapSnapshot(this.isolate, chunks, nodeCount) :
+      graph = new ObjectGraph(chunks, nodeCount),
+      timeStamp = new DateTime.now();
 
   List<Future<ServiceObject>> getMostRetained({int classId, int limit}) {
     var result = [];
@@ -795,8 +797,6 @@
     }
     return result;
   }
-
-
 }
 
 /// State for a running isolate.
@@ -857,6 +857,20 @@
         .then(_buildClassHierarchy);
   }
 
+  Future<List<Class>> getClassRefs() async {
+    ServiceMap classList = await invokeRpc('getClassList', {});
+    assert(classList.type == 'ClassList');
+    var classRefs = [];
+    for (var cls in classList['classes']) {
+      // Skip over non-class classes.
+      if (cls is Class) {
+        _classesByCid[cls.vmCid] = cls;
+        classRefs.add(cls);
+      }
+    }
+    return classRefs;
+  }
+
   /// Given the class list, loads each class.
   Future<List<Class>> _loadClasses(ServiceMap classList) {
     assert(classList.type == 'ClassList');
@@ -864,6 +878,7 @@
     for (var cls in classList['classes']) {
       // Skip over non-class classes.
       if (cls is Class) {
+        _classesByCid[cls.vmCid] = cls;
         futureClasses.add(cls.load());
       }
     }
@@ -886,6 +901,8 @@
     return new Future.value(objectClass);
   }
 
+  Class getClassByCid(int cid) => _classesByCid[cid];
+
   ServiceObject getFromMap(ObservableMap map) {
     if (map == null) {
       return null;
@@ -938,6 +955,7 @@
 
   @observable Class objectClass;
   @observable final rootClasses = new ObservableList<Class>();
+  Map<int, Class> _classesByCid = new Map<int, Class>();
 
   @observable Library rootLibrary;
   @observable ObservableList<Library> libraries =
@@ -958,21 +976,51 @@
 
   @observable DartError error;
   @observable HeapSnapshot latestSnapshot;
-  Completer<HeapSnapshot> _snapshotFetch;
+  StreamController _snapshotFetch;
+
+  List<ByteData> _chunksInProgress;
 
   void _loadHeapSnapshot(ServiceEvent event) {
-    latestSnapshot = new HeapSnapshot(this, event.data);
+    if (_snapshotFetch == null || _snapshotFetch.isClosed) {
+      // No outstanding snapshot request. Presumably another client asked for a
+      // snapshot.
+      Logger.root.info("Dropping unsolicited heap snapshot chunk");
+      return;
+    }
+
+    // Occasionally these actually arrive out of order.
+    var chunkIndex = event.chunkIndex;
+    var chunkCount = event.chunkCount;
+    if (_chunksInProgress == null) {
+      _chunksInProgress = new List(chunkCount);
+    }
+    _chunksInProgress[chunkIndex] = event.data;
+    _snapshotFetch.add("Receiving snapshot chunk ${chunkIndex + 1}"
+                       " of $chunkCount...");
+
+    for (var i = 0; i < chunkCount; i++) {
+      if (_chunksInProgress[i] == null) return;
+    }
+
+    var loadedChunks = _chunksInProgress;
+    _chunksInProgress = null;
+
+    latestSnapshot = new HeapSnapshot(this, loadedChunks, event.nodeCount);
     if (_snapshotFetch != null) {
-      _snapshotFetch.complete(latestSnapshot);
+      latestSnapshot.graph.process(_snapshotFetch).then((graph) {
+        _snapshotFetch.add(latestSnapshot);
+        _snapshotFetch.close();
+      });
     }
   }
 
-  Future<HeapSnapshot> fetchHeapSnapshot() {
-    if (_snapshotFetch == null || _snapshotFetch.isCompleted) {
-      _snapshotFetch = new Completer<HeapSnapshot>();
-      isolate.invokeRpcNoUpgrade('requestHeapSnapshot', {});
+  Stream fetchHeapSnapshot() {
+    if (_snapshotFetch == null || _snapshotFetch.isClosed) {
+      _snapshotFetch = new StreamController();
+      // isolate.vm.streamListen('_Graph');
+      isolate.invokeRpcNoUpgrade('_requestHeapSnapshot', {});
     }
-    return _snapshotFetch.future;
+    return _snapshotFetch.stream;
   }
 
   void updateHeapsFromMap(ObservableMap map) {
@@ -991,12 +1039,6 @@
     loading = false;
 
     _upgradeCollection(map, isolate);
-    if (map['rootLib'] == null ||
-        map['timers'] == null ||
-        map['heaps'] == null) {
-      Logger.root.severe("Malformed 'Isolate' response: $map");
-      return;
-    }
     rootLibrary = map['rootLib'];
     if (map['entry'] != null) {
       entry = map['entry'];
@@ -1004,7 +1046,7 @@
     var startTimeInMillis = map['startTime'];
     startTime = new DateTime.fromMillisecondsSinceEpoch(startTimeInMillis);
     notifyPropertyChange(#upTime, 0, 1);
-    var countersMap = map['tagCounters'];
+    var countersMap = map['_tagCounters'];
     if (countersMap != null) {
       var names = countersMap['names'];
       var counts = countersMap['counters'];
@@ -1039,17 +1081,9 @@
                       timerMap['time_bootstrap']);
     timers['dart'] = timerMap['time_dart_execution'];
 
-    updateHeapsFromMap(map['heaps']);
+    updateHeapsFromMap(map['_heaps']);
     _updateBreakpoints(map['breakpoints']);
 
-    List features = map['features'];
-    if (features != null) {
-      for (var feature in features) {
-        if (feature == 'io') {
-          ioEnabled = true;
-        }
-      }
-    }
     pauseEvent = map['pauseEvent'];
     _updateRunState();
     error = map['error'];
@@ -1060,7 +1094,7 @@
   }
 
   Future<TagProfile> updateTagProfile() {
-    return isolate.invokeRpcNoUpgrade('getTagProfile', {}).then(
+    return isolate.invokeRpcNoUpgrade('_getTagProfile', {}).then(
       (ObservableMap map) {
         var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0;
         tagProfile._processTagProfile(seconds, map);
@@ -1172,6 +1206,11 @@
                      { 'functionId': function.id });
   }
 
+  Future<ServiceObject> addBreakOnActivation(Instance closure) {
+    return invokeRpc('_addBreakpointAtActivation',
+                     { 'objectId': closure.id });
+  }
+
   Future removeBreakpoint(Breakpoint bpt) {
     return invokeRpc('removeBreakpoint',
                      { 'breakpointId': bpt.id });
@@ -1250,7 +1289,7 @@
     Map params = {
       'onlyWithInstantiations': onlyWithInstantiations,
     };
-    return invokeRpc('getTypeArgumentsList', params);
+    return invokeRpc('_getTypeArgumentsList', params);
   }
 
   Future<ServiceObject> getInstances(Class cls, var limit) {
@@ -1266,7 +1305,7 @@
       'address': address,
       'ref': ref,
     };
-    return invokeRpc('getObjectByAddress', params);
+    return invokeRpc('_getObjectByAddress', params);
   }
 
   final ObservableMap<String, ServiceMetric> dartMetrics =
@@ -1278,7 +1317,7 @@
   Future<ObservableMap<String, ServiceMetric>> _refreshMetrics(
       String metricType,
       ObservableMap<String, ServiceMetric> metricsMap) {
-    return invokeRpc('getIsolateMetricList',
+    return invokeRpc('_getIsolateMetricList',
                      { 'type': metricType }).then((result) {
       // Clear metrics map.
       metricsMap.clear();
@@ -1424,6 +1463,7 @@
   @observable ByteData data;
   @observable int count;
   @observable String reason;
+  int chunkIndex, chunkCount, nodeCount;
 
   @observable bool get isPauseEvent {
     return (eventType == kPauseStart ||
@@ -1456,6 +1496,15 @@
     if (map['_data'] != null) {
       data = map['_data'];
     }
+    if (map['chunkIndex'] != null) {
+      chunkIndex = map['chunkIndex'];
+    }
+    if (map['chunkCount'] != null) {
+      chunkCount = map['chunkCount'];
+    }
+    if (map['nodeCount'] != null) {
+      nodeCount = map['nodeCount'];
+    }
     if (map['count'] != null) {
       count = map['count'];
     }
@@ -1539,7 +1588,7 @@
 }
 
 class Library extends ServiceObject with Coverage {
-  @observable String url;
+  @observable String uri;
   @reflectable final imports = new ObservableList<Library>();
   @reflectable final scripts = new ObservableList<Script>();
   @reflectable final classes = new ObservableList<Class>();
@@ -1552,16 +1601,16 @@
   Library._empty(ServiceObjectOwner owner) : super._empty(owner);
 
   void _update(ObservableMap map, bool mapIsRef) {
-    url = map['url'];
-    var shortUrl = url;
-    if (url.startsWith('file://') ||
-        url.startsWith('http://')) {
-      shortUrl = url.substring(url.lastIndexOf('/') + 1);
+    uri = map['uri'];
+    var shortUri = uri;
+    if (uri.startsWith('file://') ||
+        uri.startsWith('http://')) {
+      shortUri = uri.substring(uri.lastIndexOf('/') + 1);
     }
     name = map['name'];
     if (name.isEmpty) {
-      // When there is no name for a library, use the shortUrl.
-      name = shortUrl;
+      // When there is no name for a library, use the shortUri.
+      name = shortUri;
     }
     vmName = (map.containsKey('vmName') ? map['vmName'] : name);
     if (mapIsRef) {
@@ -1588,7 +1637,7 @@
     return isolate._eval(this, expression);
   }
 
-  String toString() => "Library($url)";
+  String toString() => "Library($uri)";
 }
 
 class AllocationCount extends Observable {
@@ -1750,8 +1799,8 @@
   @observable int retainedSize;
   @observable String valueAsString;  // If primitive.
   @observable bool valueAsStringIsTruncated;
-  @observable ServiceFunction closureFunc;  // If a closure.
-  @observable Context closureCtxt;  // If a closure.
+  @observable ServiceFunction function;  // If a closure.
+  @observable Context context;  // If a closure.
   @observable String name;  // If a Type.
   @observable int length; // If a List.
 
@@ -1764,7 +1813,7 @@
   @observable Instance key;  // If a WeakProperty.
   @observable Instance value;  // If a WeakProperty.
 
-  bool get isClosure => closureFunc != null;
+  bool get isClosure => function != null;
 
   Instance._empty(ServiceObjectOwner owner) : super._empty(owner);
 
@@ -1777,8 +1826,8 @@
     valueAsString = map['valueAsString'];
     // Coerce absence to false.
     valueAsStringIsTruncated = map['valueAsStringIsTruncated'] == true;
-    closureFunc = map['closureFunc'];
-    closureCtxt = map['closureCtxt'];
+    function = map['function'];
+    context = map['context'];
     name = map['name'];
     length = map['length'];
 
@@ -1801,7 +1850,7 @@
 
   String get shortName {
     if (isClosure) {
-      return closureFunc.qualifiedName;
+      return function.qualifiedName;
     }
     if (valueAsString != null) {
       return valueAsString;
@@ -2173,6 +2222,7 @@
   Set<CallSite> callSites = new Set<CallSite>();
   final lines = new ObservableList<ScriptLine>();
   final _hits = new Map<int, int>();
+  @observable String uri;
   @observable String kind;
   @observable int firstTokenPos;
   @observable int lastTokenPos;
@@ -2182,8 +2232,7 @@
   bool get canCache => true;
   bool get immutable => true;
 
-  String _shortUrl;
-  String _url;
+  String _shortUri;
 
   Script._empty(ServiceObjectOwner owner) : super._empty(owner);
 
@@ -2203,11 +2252,11 @@
 
   void _update(ObservableMap map, bool mapIsRef) {
     _upgradeCollection(map, isolate);
-    kind = map['kind'];
-    _url = map['name'];
-    _shortUrl = _url.substring(_url.lastIndexOf('/') + 1);
-    name = _shortUrl;
-    vmName = _url;
+    uri = map['uri'];
+    kind = map['_kind'];
+    _shortUri = uri.substring(uri.lastIndexOf('/') + 1);
+    name = _shortUri;
+    vmName = uri;
     if (mapIsRef) {
       return;
     }
@@ -2293,7 +2342,7 @@
       return;
     }
     lines.clear();
-    Logger.root.info('Adding ${sourceLines.length} source lines for ${_url}');
+    Logger.root.info('Adding ${sourceLines.length} source lines for ${uri}');
     for (var i = 0; i < sourceLines.length; i++) {
       lines.add(new ScriptLine(this, i + lineOffset + 1, sourceLines[i]));
     }
@@ -2369,7 +2418,7 @@
     if (lastLine == null) {
       return r;
     }
-    
+
     final lastColumn = tokenToCol(endTokenPos);
     if (lastColumn == null) {
       return r;
@@ -3000,7 +3049,7 @@
 
   Future<ObservableMap> _fetchDirect() {
     assert(owner is Isolate);
-    return isolate.invokeRpcNoUpgrade('getIsolateMetric', { 'metricId': id });
+    return isolate.invokeRpcNoUpgrade('_getIsolateMetric', { 'metricId': id });
   }
 
 
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index 91b2b51..98cbca2 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -9,7 +9,6 @@
     'lib/cli.dart',
     'lib/cpu_profile.dart',
     'lib/debugger.dart',
-    'lib/dominator_tree.dart',
     'lib/elements.dart',
     'lib/elements.html',
     'lib/object_graph.dart',
@@ -75,6 +74,8 @@
     'lib/src/elements/heap_map.html',
     'lib/src/elements/heap_profile.dart',
     'lib/src/elements/heap_profile.html',
+    'lib/src/elements/heap_snapshot.dart',
+    'lib/src/elements/heap_snapshot.html',
     'lib/src/elements/inbound_reference.dart',
     'lib/src/elements/inbound_reference.html',
     'lib/src/elements/instance_ref.dart',
diff --git a/runtime/observatory/tests/service/allocations_test.dart b/runtime/observatory/tests/service/allocations_test.dart
index f305d89..0882edc 100644
--- a/runtime/observatory/tests/service/allocations_test.dart
+++ b/runtime/observatory/tests/service/allocations_test.dart
@@ -21,7 +21,7 @@
 
 (Isolate isolate) =>
   isolate.rootLibrary.load().then((Library lib) {
-    expect(lib.url.endsWith('allocations_test.dart'), isTrue);
+    expect(lib.uri.endsWith('allocations_test.dart'), isTrue);
     expect(lib.classes.length, equals(1));
     return lib.classes.first.load().then((Class fooClass) {
       expect(fooClass.name, equals('Foo'));
diff --git a/runtime/observatory/tests/service/break_on_activation_test.dart b/runtime/observatory/tests/service/break_on_activation_test.dart
new file mode 100644
index 0000000..0b20631
--- /dev/null
+++ b/runtime/observatory/tests/service/break_on_activation_test.dart
@@ -0,0 +1,191 @@
+// 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=--compile-all --error_on_bad_type --error_on_bad_override
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+import 'dart:async';
+
+genRepeater(value) {
+  return () => print(value);
+}
+
+genRepeaterNamed(value) {
+  return ({x, y}) => print(value);
+}
+
+var r1;
+var r2;
+var r3;
+
+var r1_named;
+var r2_named;
+var r3_named;
+
+void testeeSetup() {
+  // These closures have the same function.
+  r1 = genRepeater('r1');
+  r2 = genRepeater('r2');
+  r3 = genRepeater('r3');
+
+  // These closures have the same function.
+  r1_named = genRepeaterNamed('r1_named');
+  r2_named = genRepeaterNamed('r2_named');
+  r3_named = genRepeaterNamed('r3_named');
+}
+
+void testeeDo() {
+  r1();
+  r2();
+  r3();
+}
+
+void testeeDoNamed() {
+  r1_named(y: 'Not a closure', x: 'Not a closure');
+  r2_named(y: 'Not a closure', x: 'Not a closure');
+  r3_named(y: 'Not a closure', x: 'Not a closure');
+}
+
+
+var tests = [
+(Isolate isolate) async {
+  var rootLib = await isolate.rootLibrary.load();
+
+  var breaksHit = 0;
+
+  var subscription;
+  subscription = isolate.vm.events.stream.listen((ServiceEvent event) {
+    if (event.eventType == ServiceEvent.kPauseBreakpoint) {
+      print("Hit breakpoint ${event.breakpoint}");
+      breaksHit++;
+      isolate.resume();
+    }
+  });
+
+  valueOfField(String name) {
+    return rootLib.variables.singleWhere((v) => v.name == name).value;
+  }
+  var r1Ref = valueOfField('r1');
+  var r2Ref = valueOfField('r2');
+  var r3Ref = valueOfField('r3');
+
+  var bpt1 = await isolate.addBreakOnActivation(r1Ref);
+  print("Added breakpoint $bpt1");
+  expect(bpt1 is Breakpoint, isTrue);
+  expect(breaksHit, equals(0));
+  print("testeeDo()");
+  var res = await rootLib.evaluate("testeeDo()");
+  expect(res is Instance, isTrue); // Not error.
+  expect(breaksHit, equals(1));
+
+  await isolate.removeBreakpoint(bpt1);
+  print("Removed breakpoint $bpt1");
+  print("testeeDo()");
+  res = await rootLib.evaluate("testeeDo()");
+  expect(res is Instance, isTrue); // Not error.
+  expect(breaksHit, equals(1));
+
+  await subscription.cancel();
+},
+
+(Isolate isolate) async {
+  var rootLib = await isolate.rootLibrary.load();
+
+  var breaksHit = 0;
+
+  var subscription;
+  subscription = isolate.vm.events.stream.listen((ServiceEvent event) {
+    if (event.eventType == ServiceEvent.kPauseBreakpoint) {
+      print("Hit breakpoint ${event.breakpoint}");
+      breaksHit++;
+      isolate.resume();
+    }
+  });
+
+  valueOfField(String name) {
+    return rootLib.variables.singleWhere((v) => v.name == name).value;
+  }
+  var r1Ref = valueOfField('r1_named');
+  var r2Ref = valueOfField('r2_named');
+  var r3Ref = valueOfField('r3_named');
+
+  var bpt1 = await isolate.addBreakOnActivation(r1Ref);
+  print("Added breakpoint $bpt1");
+  expect(bpt1 is Breakpoint, isTrue);
+  expect(breaksHit, equals(0));
+  print("testeeDoNamed()");
+  var res = await rootLib.evaluate("testeeDoNamed()");
+  expect(res is Instance, isTrue); // Not error.
+  expect(breaksHit, equals(1));
+
+  await isolate.removeBreakpoint(bpt1);
+  print("Removed breakpoint $bpt1");
+  print("testeeDoNamed()");
+  res = await rootLib.evaluate("testeeDoNamed()");
+  expect(res is Instance, isTrue); // Not error.
+  expect(breaksHit, equals(1));
+
+  await subscription.cancel();
+},
+
+(Isolate isolate) async {
+  var rootLib = await isolate.rootLibrary.load();
+
+  var breaksHit = 0;
+
+  var subscription;
+  subscription = isolate.vm.events.stream.listen((ServiceEvent event) {
+    if (event.eventType == ServiceEvent.kPauseBreakpoint) {
+      print("Hit breakpoint ${event.breakpoint}");
+      breaksHit++;
+      isolate.resume();
+    }
+  });
+
+  valueOfField(String name) {
+    return rootLib.variables.singleWhere((v) => v.name == name).value;
+  }
+  var r1Ref = valueOfField('r1');
+  var r2Ref = valueOfField('r2');
+  var r3Ref = valueOfField('r3');
+
+  var bpt1 = await isolate.addBreakOnActivation(r1Ref);
+  print("Added breakpoint $bpt1");
+  expect(bpt1 is Breakpoint, isTrue);
+  expect(breaksHit, equals(0));
+  print("testeeDo()");
+  var res = await rootLib.evaluate("testeeDo()");
+  expect(res is Instance, isTrue); // Not error.
+  expect(breaksHit, equals(1));
+
+  var bpt2 = await isolate.addBreakOnActivation(r2Ref);
+  print("Added breakpoint $bpt2");
+  expect(bpt2 is Breakpoint, isTrue);
+  expect(breaksHit, equals(1));
+  print("testeeDo()");
+  res = await rootLib.evaluate("testeeDo()");
+  expect(res is Instance, isTrue); // Not error.
+  expect(breaksHit, equals(3));
+
+  await isolate.removeBreakpoint(bpt1);
+  print("Removed breakpoint $bpt1");
+  print("testeeDo()");
+  res = await rootLib.evaluate("testeeDo()");
+  expect(res is Instance, isTrue); // Not error.
+  expect(breaksHit, equals(4));
+
+  await isolate.removeBreakpoint(bpt2);
+  print("Removed breakpoint $bpt2");
+  print("testeeDo()");
+  res = await rootLib.evaluate("testeeDo()");
+  expect(res is Instance, isTrue); // Not error.
+  expect(breaksHit, equals(4));
+
+  await subscription.cancel();
+},
+
+];
+
+main(args) => runIsolateTests(args, tests, testeeBefore: testeeSetup);
diff --git a/runtime/observatory/tests/service/contexts_test.dart b/runtime/observatory/tests/service/contexts_test.dart
index 3954d87..6bbcacd 100644
--- a/runtime/observatory/tests/service/contexts_test.dart
+++ b/runtime/observatory/tests/service/contexts_test.dart
@@ -55,9 +55,9 @@
     Field field = lib.variables.singleWhere((v) => v.name == 'cleanBlock');
     return field.value.load().then((Instance block) {
       expect(block.isClosure, isTrue);
-      expect(block.closureCtxt.isContext, isTrue);
-      expect(block.closureCtxt.length, equals(0));
-      return block.closureCtxt.load().then((Context ctxt) {
+      expect(block.context.isContext, isTrue);
+      expect(block.context.length, equals(0));
+      return block.context.load().then((Context ctxt) {
         expect(ctxt.parentContext.isNull, isTrue);
       });
     });
@@ -68,9 +68,9 @@
     Field field = lib.variables.singleWhere((v) => v.name == 'copyingBlock');
     return field.value.load().then((Instance block) {
       expect(block.isClosure, isTrue);
-      expect(block.closureCtxt.isContext, isTrue);
-      expect(block.closureCtxt.length, equals(1));
-      return block.closureCtxt.load().then((Context ctxt) {
+      expect(block.context.isContext, isTrue);
+      expect(block.context.length, equals(1));
+      return block.context.load().then((Context ctxt) {
         expect(ctxt.variables.single['value'].isString, isTrue);
         expect(ctxt.variables.single['value'].valueAsString, equals('I could be copied into the block'));
         expect(ctxt.parentContext.isContext, isTrue);
@@ -87,9 +87,9 @@
     Field field = lib.variables.singleWhere((v) => v.name == 'fullBlock');
     return field.value.load().then((Instance block) {
       expect(block.isClosure, isTrue);
-      expect(block.closureCtxt.isContext, isTrue);
-      expect(block.closureCtxt.length, equals(1));
-      return block.closureCtxt.load().then((ctxt) {
+      expect(block.context.isContext, isTrue);
+      expect(block.context.length, equals(1));
+      return block.context.load().then((ctxt) {
         expect(ctxt.variables.single['value'].isInt, isTrue);
         expect(ctxt.variables.single['value'].valueAsString, equals('43'));
         expect(ctxt.parentContext.isContext, isTrue);
@@ -106,9 +106,9 @@
     Field field = lib.variables.singleWhere((v) => v.name == 'fullBlockWithChain');
     return field.value.load().then((Instance block) {
       expect(block.isClosure, isTrue);
-      expect(block.closureCtxt.isContext, isTrue);
-      expect(block.closureCtxt.length, equals(1));
-      return block.closureCtxt.load().then((Context ctxt) {
+      expect(block.context.isContext, isTrue);
+      expect(block.context.length, equals(1));
+      return block.context.load().then((Context ctxt) {
         expect(ctxt.variables.single['value'].isInt, isTrue);
         expect(ctxt.variables.single['value'].valueAsString, equals('4201'));
         expect(ctxt.parentContext.isContext, isTrue);
diff --git a/runtime/observatory/tests/service/coverage_test.dart b/runtime/observatory/tests/service/coverage_test.dart
index 54e9080..9a4fc59 100644
--- a/runtime/observatory/tests/service/coverage_test.dart
+++ b/runtime/observatory/tests/service/coverage_test.dart
@@ -94,7 +94,7 @@
 
       List tests = [];
       // Function
-      tests.add(isolate.invokeRpcNoUpgrade('getCoverage',
+      tests.add(isolate.invokeRpcNoUpgrade('_getCoverage',
                                            { 'targetId': func.id })
                 .then((Map coverage) {
                     expect(coverage['type'], equals('CodeCoverage'));
@@ -103,7 +103,7 @@
                            equals([15, 1, 16, 1, 17, 0, 19, 1]));
                 }));
       // Class
-      tests.add(isolate.invokeRpcNoUpgrade('getCoverage',
+      tests.add(isolate.invokeRpcNoUpgrade('_getCoverage',
                                            { 'targetId': cls.id })
                 .then((Map coverage) {
                     expect(coverage['type'], equals('CodeCoverage'));
@@ -113,7 +113,7 @@
                                    24, 1, 25, 1, 27, 0]));
                 }));
       // Library
-      tests.add(isolate.invokeRpcNoUpgrade('getCoverage',
+      tests.add(isolate.invokeRpcNoUpgrade('_getCoverage',
                                            { 'targetId': lib.id })
                 .then((Map coverage) {
                     expect(coverage['type'], equals('CodeCoverage'));
@@ -126,7 +126,7 @@
                 }));
       // Script
       tests.add(cls.load().then((_) {
-            return isolate.invokeRpcNoUpgrade('getCoverage',
+            return isolate.invokeRpcNoUpgrade('_getCoverage',
                                               { 'targetId': cls.script.id })
                 .then((Map coverage) {
                     expect(coverage['type'], equals('CodeCoverage'));
@@ -140,7 +140,7 @@
           }));
       // Isolate
       tests.add(cls.load().then((_) {
-            return isolate.invokeRpcNoUpgrade('getCoverage', {})
+            return isolate.invokeRpcNoUpgrade('_getCoverage', {})
                 .then((Map coverage) {
                     expect(coverage['type'], equals('CodeCoverage'));
                     expect(coverage['coverage'].length, greaterThan(100));
diff --git a/runtime/observatory/tests/service/dominator_tree_test.dart b/runtime/observatory/tests/service/dominator_tree_test.dart
index 35bce6a..b5c6566 100644
--- a/runtime/observatory/tests/service/dominator_tree_test.dart
+++ b/runtime/observatory/tests/service/dominator_tree_test.dart
@@ -1,55 +1,86 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// 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=--compile-all --error_on_bad_type --error_on_bad_override
 
-import 'package:observatory/dominator_tree.dart';
+import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+import 'dart:async';
 
-void main() {
-  test('small example from [Lenguaer & Tarjan 1979]', smallTest);
-  test('non-flowgraph', nonFlowgraph);
+// small example from [Lenguaer & Tarjan 1979]
+class R { var x; var y; var z; }
+class A { var x; }
+class B { var x; var y; var z; }
+class C { var x; var y; }
+class D { var x; }
+class E { var x; }
+class F { var x; }
+class G { var x; var y; }
+class H { var x; var y; }
+class I { var x; }
+class J { var x; }
+class K { var x; var y; }
+class L { var x; }
+
+var r;
+
+buildGraph() {
+  r = new R();
+  var a = new A();
+  var b = new B();
+  var c = new C();
+  var d = new D();
+  var e = new E();
+  var f = new F();
+  var g = new G();
+  var h = new H();
+  var i = new I();
+  var j = new J();
+  var k = new K();
+  var l = new L();
+
+  r.x = a; r.y = b; r.z = c;
+  a.x = d;
+  b.x = a; b.y = d; b.z = e;
+  c.x = f; c.y = g;
+  d.x = l;
+  e.x = h;
+  f.x = i;
+  g.x = i; g.y = j;
+  h.x = e; h.y = k;
+  i.x = k;
+  j.x = i;
+  k.x = i; k.y = r;
+  l.x = h;
 }
 
-void smallTest() {
-  var g = {
-    'R': ['A', 'B', 'C'],
-    'A': ['D'],
-    'B': ['A', 'D', 'E'],
-    'C': ['F', 'G'],
-    'D': ['L'],
-    'E': ['H'],
-    'F': ['I'],
-    'G': ['I', 'J'],
-    'H': ['E', 'K'],
-    'I': ['K'],
-    'J': ['I'],
-    'K': ['I', 'R'],
-    'L': ['H'],
-  };
-  var d = new Dominator();
-  for (String u in g.keys) {
-    d.addEdges(u, g[u]);
+var tests = [
+(Isolate isolate) async {
+  var rootLib = await isolate.rootLibrary.load();
+  var snapshot = await isolate.fetchHeapSnapshot().last;
+
+  node(String className) {
+    var cls = rootLib.classes.singleWhere((cls) => cls.name == className);
+    return snapshot.graph.vertices.singleWhere((v) => v.vmCid == cls.vmCid);
   }
-  d.computeDominatorTree('R');
-  expect(d.dominator('I'), equals('R'));
-  expect(d.dominator('K'), equals('R'));
-  expect(d.dominator('C'), equals('R'));
-  expect(d.dominator('H'), equals('R'));
-  expect(d.dominator('E'), equals('R'));
-  expect(d.dominator('A'), equals('R'));
-  expect(d.dominator('D'), equals('R'));
-  expect(d.dominator('B'), equals('R'));
 
-  expect(d.dominator('F'), equals('C'));
-  expect(d.dominator('G'), equals('C'));
-  expect(d.dominator('J'), equals('G'));
-  expect(d.dominator('L'), equals('D'));
-  expect(d.dominator('R'), isNull);
-}
+  expect(node('I').dominator, equals(node('R')));
+  expect(node('K').dominator, equals(node('R')));
+  expect(node('C').dominator, equals(node('R')));
+  expect(node('H').dominator, equals(node('R')));
+  expect(node('E').dominator, equals(node('R')));
+  expect(node('A').dominator, equals(node('R')));
+  expect(node('D').dominator, equals(node('R')));
+  expect(node('B').dominator, equals(node('R')));
 
-void nonFlowgraph() {
-  var d = new Dominator();
-  d.addEdges('A', ['B']);
-  expect(() => d.computeDominatorTree('B'), throwsStateError);
-}
+  expect(node('F').dominator, equals(node('C')));
+  expect(node('G').dominator, equals(node('C')));
+  expect(node('J').dominator, equals(node('G')));
+  expect(node('L').dominator, equals(node('D')));
+
+  expect(node('R'), isNotNull);  // The field.
+},
+];
+
+main(args) => runIsolateTests(args, tests, testeeBefore: buildGraph);
diff --git a/runtime/observatory/tests/service/get_flag_list_rpc_test.dart b/runtime/observatory/tests/service/get_flag_list_rpc_test.dart
index d726c2b..f05def6 100644
--- a/runtime/observatory/tests/service/get_flag_list_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_flag_list_rpc_test.dart
@@ -22,7 +22,7 @@
       'name' : 'does_not_really_exist',
       'value' : 'true',
     };
-    var result = await vm.invokeRpcNoUpgrade('setFlag', params);
+    var result = await vm.invokeRpcNoUpgrade('_setFlag', params);
     expect(result['type'], equals('Error'));
     expect(result['message'], equals('Cannot set flag: flag not found'));
   },
@@ -34,7 +34,7 @@
       'name' : 'trace_isolates',
       'value' : '123',
     };
-    var result = await vm.invokeRpcNoUpgrade('setFlag', params);
+    var result = await vm.invokeRpcNoUpgrade('_setFlag', params);
     expect(result['type'], equals('Error'));
     expect(result['message'], equals('Cannot set flag: invalid value'));
   },
diff --git a/runtime/observatory/tests/service/get_heap_map_rpc_test.dart b/runtime/observatory/tests/service/get_heap_map_rpc_test.dart
index 3fda617..5247ca9 100644
--- a/runtime/observatory/tests/service/get_heap_map_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_heap_map_rpc_test.dart
@@ -12,7 +12,7 @@
   (Isolate isolate) async {
     var params = {
     };
-    var result = await isolate.invokeRpcNoUpgrade('getHeapMap', params);
+    var result = await isolate.invokeRpcNoUpgrade('_getHeapMap', params);
     expect(result['type'], equals('HeapMap'));
     expect(result['freeClassId'], isPositive);
     expect(result['unitSizeBytes'], isPositive);
diff --git a/runtime/observatory/tests/service/get_isolate_rpc_test.dart b/runtime/observatory/tests/service/get_isolate_rpc_test.dart
index 146ff5f..6414ae2 100644
--- a/runtime/observatory/tests/service/get_isolate_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_isolate_rpc_test.dart
@@ -26,10 +26,8 @@
     expect(result['libraries'].length, isPositive);
     expect(result['libraries'][0]['type'], equals('@Library'));
     expect(result['breakpoints'].length, isZero);
-    expect(result['features'].length, isPositive);
-    expect(result['features'][0], new isInstanceOf<String>());
-    expect(result['heaps']['new']['type'], equals('HeapSpace'));
-    expect(result['heaps']['old']['type'], equals('HeapSpace'));
+    expect(result['_heaps']['new']['type'], equals('HeapSpace'));
+    expect(result['_heaps']['old']['type'], equals('HeapSpace'));
   },
 ];
 
diff --git a/runtime/observatory/tests/service/get_object_rpc_test.dart b/runtime/observatory/tests/service/get_object_rpc_test.dart
index 2fedac5..1d5f507 100644
--- a/runtime/observatory/tests/service/get_object_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_object_rpc_test.dart
@@ -123,8 +123,8 @@
     expect(result['type'], equals('Library'));
     expect(result['id'], startsWith('libraries/'));
     expect(result['name'], equals('get_object_rpc_test'));
-    expect(result['url'], startsWith('file:'));
-    expect(result['url'], endsWith('get_object_rpc_test.dart'));
+    expect(result['uri'], startsWith('file:'));
+    expect(result['uri'], endsWith('get_object_rpc_test.dart'));
     expect(result['imports'].length, isPositive);
     expect(result['imports'][0]['type'], equals('@Library'));
     expect(result['scripts'].length, isPositive);
@@ -169,9 +169,9 @@
     var result = await isolate.invokeRpcNoUpgrade('getObject', params);
     expect(result['type'], equals('Script'));
     expect(result['id'], startsWith('libraries/'));
-    expect(result['name'], startsWith('file:'));
-    expect(result['name'], endsWith('get_object_rpc_test.dart'));
-    expect(result['kind'], equals('script'));
+    expect(result['uri'], startsWith('file:'));
+    expect(result['uri'], endsWith('get_object_rpc_test.dart'));
+    expect(result['_kind'], equals('script'));
     expect(result['library']['type'], equals('@Library'));
     expect(result['source'], startsWith('// Copyright (c)'));
     expect(result['tokenPosTable'].length, isPositive);
diff --git a/runtime/observatory/tests/service/graph_test.dart b/runtime/observatory/tests/service/graph_test.dart
index 6160fa3..9b0b937 100644
--- a/runtime/observatory/tests/service/graph_test.dart
+++ b/runtime/observatory/tests/service/graph_test.dart
@@ -37,61 +37,55 @@
 
 var tests = [
 
-(Isolate isolate) {
-  Completer completer = new Completer();
-  isolate.vm.events.stream.listen((ServiceEvent event) {
-    if (event.eventType == ServiceEvent.kGraph) {
-      ReadStream reader = new ReadStream(event.data);
-      ObjectGraph graph = new ObjectGraph(reader);
-      expect(fooId, isNotNull);
-      Iterable<ObjectVertex> foos = graph.vertices.where(
-          (ObjectVertex obj) => obj.classId == fooId);
-      expect(foos.length, equals(3));
-      expect(foos.where(
-          (ObjectVertex obj) => obj.succ.length == 0).length, equals(1));
-      expect(foos.where(
-          (ObjectVertex obj) => obj.succ.length == 1).length, equals(1));
-      expect(foos.where(
-          (ObjectVertex obj) => obj.succ.length == 2).length, equals(1));
+(Isolate isolate) async {
+  Library lib = await isolate.rootLibrary.load();
+  expect(lib.classes.length, equals(1));
+  Class fooClass = lib.classes.first;
+  fooId = fooClass.vmCid;
 
-      ObjectVertex bVertex = foos.where(
-          (ObjectVertex obj) => obj.succ.length == 0).first;
-      ObjectVertex aVertex = foos.where(
-          (ObjectVertex obj) => obj.succ.length == 1).first;
-      ObjectVertex rVertex = foos.where(
-          (ObjectVertex obj) => obj.succ.length == 2).first;
+  HeapSnapshot snapshot = await isolate.fetchHeapSnapshot().last;
+  ObjectGraph graph = snapshot.graph;
 
-      // TODO(koda): Check actual byte sizes.
+  expect(fooId, isNotNull);
+  Iterable<ObjectVertex> foos = graph.vertices.where(
+      (ObjectVertex obj) => obj.vmCid == fooId);
+  expect(foos.length, equals(3));
+  expect(foos.where((obj) => obj.successors.length == 0).length,
+         equals(1));
+  expect(foos.where((obj) => obj.successors.length == 1).length,
+         equals(1));
+  expect(foos.where((obj) => obj.successors.length == 2).length,
+         equals(1));
 
-      expect(aVertex.retainedSize, equals(aVertex.shallowSize));
-      expect(bVertex.retainedSize, equals(bVertex.shallowSize));
-      expect(rVertex.retainedSize, equals(aVertex.shallowSize +
-                                          bVertex.shallowSize +
-                                          rVertex.shallowSize));
+  ObjectVertex bVertex = foos.where(
+      (ObjectVertex obj) => obj.successors.length == 0).first;
+  ObjectVertex aVertex = foos.where(
+      (ObjectVertex obj) => obj.successors.length == 1).first;
+  ObjectVertex rVertex = foos.where(
+      (ObjectVertex obj) => obj.successors.length == 2).first;
 
-      const int fixedSizeListCid = 61;
-      List<ObjectVertex> lists = new List.from(graph.vertices.where(
-          (ObjectVertex obj) => obj.classId == fixedSizeListCid));
-      expect(lists.length >= 2, isTrue);
-      // Order by decreasing retained size.
-      lists.sort((u, v) => v.retainedSize - u.retainedSize);
-      ObjectVertex first = lists[0];
-      ObjectVertex second = lists[1];
-      // Check that the short list retains more than the long list inside.
-      expect(first.succ.length, equals(2 + second.succ.length));
-      // ... and specifically, that it retains exactly itself + the long one.
-      expect(first.retainedSize,
-          equals(first.shallowSize + second.shallowSize));
-      completer.complete();
-    }
-  });
-  return isolate.rootLibrary.load().then((Library lib) {
-    expect(lib.classes.length, equals(1));
-    Class fooClass = lib.classes.first;
-    fooId = fooClass.vmCid;
-    isolate.invokeRpcNoUpgrade('requestHeapSnapshot', {});
-    return completer.future;
-  });
+  // TODO(koda): Check actual byte sizes.
+
+  expect(aVertex.retainedSize, equals(aVertex.shallowSize));
+  expect(bVertex.retainedSize, equals(bVertex.shallowSize));
+  expect(rVertex.retainedSize, equals(aVertex.shallowSize +
+                                      bVertex.shallowSize +
+                                      rVertex.shallowSize));
+
+  const int fixedSizeListCid = 61;
+  List<ObjectVertex> lists = new List.from(graph.vertices.where(
+      (ObjectVertex obj) => obj.vmCid == fixedSizeListCid));
+  expect(lists.length >= 2, isTrue);
+  // Order by decreasing retained size.
+  lists.sort((u, v) => v.retainedSize - u.retainedSize);
+  ObjectVertex first = lists[0];
+  ObjectVertex second = lists[1];
+  // Check that the short list retains more than the long list inside.
+  expect(first.successors.length,
+         equals(2 + second.successors.length));
+  // ... and specifically, that it retains exactly itself + the long one.
+  expect(first.retainedSize,
+         equals(first.shallowSize + second.shallowSize));
 },
 
 ];
diff --git a/runtime/observatory/tests/service/metrics_test.dart b/runtime/observatory/tests/service/metrics_test.dart
index 0d0535e..2d3272f 100644
--- a/runtime/observatory/tests/service/metrics_test.dart
+++ b/runtime/observatory/tests/service/metrics_test.dart
@@ -28,7 +28,7 @@
   (Isolate isolate) async {
     var params =  { 'metricId': 'metrics/a.b.c' };
     ServiceMetric counter =
-      await isolate.invokeRpc('getIsolateMetric', params);
+      await isolate.invokeRpc('_getIsolateMetric', params);
     expect(counter.name, equals('a.b.c'));
     expect(counter.value, equals(1234.5));
   },
@@ -36,14 +36,14 @@
   (Isolate isolate) async {
     bool caughtException;
     try {
-      await isolate.invokeRpc('getIsolateMetric',
+      await isolate.invokeRpc('_getIsolateMetric',
                               { 'metricId': 'metrics/a.b.d' });
       expect(false, isTrue, reason:'Unreachable');
     } on ServerRpcException catch (e) {
       caughtException = true;
       expect(e.code, equals(ServerRpcException.kInvalidParams));
       expect(e.message,
-             "getIsolateMetric: invalid 'metricId' parameter: metrics/a.b.d");
+             "_getIsolateMetric: invalid 'metricId' parameter: metrics/a.b.d");
     }
     expect(caughtException, isTrue);
   },
diff --git a/runtime/observatory/tests/service/native_metrics_test.dart b/runtime/observatory/tests/service/native_metrics_test.dart
index 0a84204..4a7182e 100644
--- a/runtime/observatory/tests/service/native_metrics_test.dart
+++ b/runtime/observatory/tests/service/native_metrics_test.dart
@@ -29,7 +29,7 @@
   (Isolate isolate) async {
     var params = { 'metricId': 'metrics/native/heap.old.used' };
     ServiceMetric counter =
-      await isolate.invokeRpc('getIsolateMetric', params);
+      await isolate.invokeRpc('_getIsolateMetric', params);
     expect(counter.type, equals('Counter'));
     expect(counter.name, equals('heap.old.used'));
   },
@@ -37,14 +37,14 @@
   (Isolate isolate) async {
     bool caughtException;
     try {
-      await isolate.invokeRpc('getIsolateMetric',
+      await isolate.invokeRpc('_getIsolateMetric',
                               { 'metricId': 'metrics/native/doesnotexist' });
       expect(false, isTrue, reason:'Unreachable');
     } on ServerRpcException catch (e) {
       caughtException = true;
       expect(e.code, equals(ServerRpcException.kInvalidParams));
       expect(e.message,
-             "getIsolateMetric: invalid 'metricId' "
+             "_getIsolateMetric: invalid 'metricId' "
              "parameter: metrics/native/doesnotexist");
     }
     expect(caughtException, isTrue);
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 6da69be..fed6ee1 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -108,6 +108,9 @@
   } else {
     var process = new _TestLauncher();
     process.launch(pause_on_exit).then((port) {
+      if (mainArgs.contains("--gdb")) {
+        port = 8181;
+      }
       String addr = 'ws://localhost:$port/ws';
       var testIndex = 1;
       var totalTests = tests.length;
@@ -192,6 +195,9 @@
   } else {
     var process = new _TestLauncher();
     process.launch(pause_on_exit).then((port) async {
+      if (mainArgs.contains("--gdb")) {
+        port = 8181;
+      }
       String addr = 'ws://localhost:$port/ws';
       var testIndex = 1;
       var totalTests = tests.length;
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 52f40f1..8bf2fb4 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -63,7 +63,7 @@
 
 # Methods can be missing in dart2js stack traces due to inlining.  Also when
 # minifying they can be renamed, which is issue 7953.
-dart/inline_stack_frame_test: RuntimeError # Issue 7953
+dart/inline_stack_frame_test: RuntimeError, Pass # Issue 7953
 
 [ $compiler == dart2js || $compiler == dartanalyzer || $compiler == dart2analyzer ]
 # Data uri's not supported by dart2js or the analyzer.
@@ -78,6 +78,7 @@
 [ $arch == mips ]
 cc/StaticNonNullSumCallCodegen: Crash, Pass # Issue 17440
 cc/ArrayLengthMaxElements: Crash  # Issue 23275
+cc/Int8ListLengthMaxElements: Skip # Issue 23536, uses 1 GB memory.
 
 [ $arch == mips && $mode == debug ]
 cc/FindCodeObject: Skip # Takes more than 8 minutes. Issue 17440
@@ -90,6 +91,3 @@
 
 [ $runtime == vm && $mode == debug && $builder_tag == asan ]
 cc/Dart2JSCompileAll: Skip  # Timeout.
-
-[ $compiler == dart2js && $cps_ir ]
-dart/error_stacktrace_test: RuntimeError # Please triage this failure.
diff --git a/runtime/tools/create_resources.py b/runtime/tools/create_resources.py
index 9632b28..27c9d78 100644
--- a/runtime/tools/create_resources.py
+++ b/runtime/tools/create_resources.py
@@ -7,13 +7,14 @@
 
 import os
 import sys
-from os.path import join
+from os.path import join, splitext
 import time
 from optparse import OptionParser
 import re
 from datetime import date
+import zlib
 
-def makeResources(root_dir, client_dir, input_files, table_name):
+def makeResources(root_dir, client_dir, input_files, table_name, compress, no_compress_extensions):
   result = ''
   resources = []
 
@@ -25,6 +26,10 @@
       resource_file_name = resource_file[ len(client_dir) : ]
     else:
       resource_file_name = resource_file
+    _, ext = os.path.splitext(resource_file)
+    if ext in no_compress_extensions:
+      # Force no compression for files of this extension.
+      compress = None
     resource_url = '/%s' % resource_file_name
     result += '// %s\n' % resource_file
     result += 'const char '
@@ -33,7 +38,10 @@
     result += '[] = {\n   '
     fileHandle = open(resource_file, 'rb')
     lineCounter = 0
-    for byte in fileHandle.read():
+    file_contents = fileHandle.read()
+    if compress:
+      file_contents = zlib.compress(file_contents)
+    for byte in file_contents:
       result += r" '\x%02x'," % ord(byte)
       lineCounter += 1
       if lineCounter == 10:
@@ -44,7 +52,7 @@
     result += ' 0\n};\n\n'
     resource_url_scrubbed = re.sub(r'\\', '/', resource_url)
     resources.append(
-        (resource_url_scrubbed, resource_name, os.stat(resource_file).st_size));
+        (resource_url_scrubbed, resource_name, len(file_contents)));
 
   # Write the resource table.
   result += 'ResourcesEntry __%s_resources_[] = ' % table_name
@@ -57,7 +65,7 @@
 
 
 def makeFile(output_file, root_dir, client_dir, input_files, outer_namespace,
-             inner_namespace, table_name):
+             inner_namespace, table_name, compress, no_compress_extensions):
   cc_text = '''
 // Copyright (c) %d, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -75,7 +83,8 @@
 };
 
 '''
-  cc_text += makeResources(root_dir, client_dir, input_files, table_name)
+  cc_text += makeResources(root_dir, client_dir, input_files, table_name,
+                           compress, no_compress_extensions)
   cc_text += '\n'
   if inner_namespace != None:
     cc_text += '}  // namespace %s\n' % inner_namespace
@@ -107,6 +116,14 @@
     parser.add_option("--client_root",
                       action="store", type="string",
                       help="root directory client resources")
+    parser.add_option("--compress",
+                      action="store_true",
+                      help="zlib compress resources")
+    parser.add_option("--no_compress_extensions",
+                      action="append",
+                      default=['.dart'],
+                      help="file extensions that should not be compressed.")
+
     (options, args) = parser.parse_args()
     if not options.output:
       sys.stderr.write('--output not specified\n')
@@ -139,7 +156,8 @@
 
     if not makeFile(options.output, options.root_prefix, options.client_root,
                     files, options.outer_namespace, options.inner_namespace,
-                    options.table_name):
+                    options.table_name, options.compress,
+                    options.no_compress_extensions):
       return -1
 
     return 0
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 27189b0..601f041 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -64,6 +64,26 @@
 }
 
 
+static_library("libdart_vm_nosnapshot") {
+  configs += ["..:dart_config"]
+  public_configs = [":libdart_vm_config"]
+  deps = [ ":generate_service_cc_file", ]
+  defines = [ "DART_NO_SNAPSHOT" ]
+  vm_sources_list = exec_script("../../tools/gypi_to_gn.py",
+                                [rebase_path("vm_sources.gypi")],
+                                "scope",
+                                ["vm_sources.gypi"])
+
+  set_sources_assignment_filter(["*_test.cc", "*_test.h"])
+  sources = vm_sources_list.sources
+            + ["$target_gen_dir/service_gen.cc",]
+            - ["vtune.cc", "vtune.h"]
+  include_dirs = [
+    "..",
+  ]
+}
+
+
 template("generate_library_source") {
   assert(defined(invoker.libname), "Need libname in $target_name")
   assert(defined(invoker.filename), "Need a filename in $target_name")
@@ -115,7 +135,7 @@
 #
 # The template iterates over the list, and generates generate_library_source
 # actions for each. After that, it generates targets to compile the generated
-# sources to make libdart_lib_withcore and libdart_lib.
+# sources to make libdart_lib_nosnapshot and libdart_lib.
 template("generate_core_libraries") {
   assert(defined(invoker.sources), "Need sources in $target_name")
   liboutputs = []
@@ -148,7 +168,7 @@
                 ":generate_${filename}_patch_cc_file"]
   }
 
-  static_library("libdart_lib_withcore") {
+  static_library("libdart_lib_nosnapshot") {
     configs += ["..:dart_config"]
     deps = libdeps
     sources = libsources + ["bootstrap.cc"] + liboutputs
@@ -172,7 +192,7 @@
     ["core", "core"],
     ["collection", "collection"],
     ["convert", "convert"],
-    ["debugger", "debugger"],
+    ["developer", "developer"],
     ["_internal", "internal"],
     ["isolate", "isolate"],
     ["math", "math"],
diff --git a/runtime/vm/assembler.h b/runtime/vm/assembler.h
index d8249ba..26f7b66 100644
--- a/runtime/vm/assembler.h
+++ b/runtime/vm/assembler.h
@@ -89,6 +89,11 @@
     cursor_ -= sizeof(T);
   }
 
+  // Return address to code at |position| bytes.
+  uword Address(intptr_t position) {
+    return contents_ + position;
+  }
+
   template<typename T> T Load(intptr_t position) {
     ASSERT(position >= 0 &&
            position <= (Size() - static_cast<intptr_t>(sizeof(T))));
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 3f50ba8..e7c2150 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -1559,7 +1559,7 @@
 
 
 void Assembler::LoadIsolate(Register rd) {
-  LoadImmediate(rd, reinterpret_cast<uword>(Isolate::Current()));
+  ldr(rd, Address(THR, Thread::isolate_offset()));
 }
 
 
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index 003e5df..91b2962 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -461,7 +461,7 @@
 
 
 void Assembler::LoadIsolate(Register dst, Register pp) {
-  LoadImmediate(dst, reinterpret_cast<uword>(Isolate::Current()), pp);
+  ldr(dst, Address(THR, Thread::isolate_offset()));
 }
 
 
diff --git a/runtime/vm/assembler_arm64_test.cc b/runtime/vm/assembler_arm64_test.cc
index a23abd3..621c03c 100644
--- a/runtime/vm/assembler_arm64_test.cc
+++ b/runtime/vm/assembler_arm64_test.cc
@@ -3553,18 +3553,22 @@
 // R0: context.
 // R1: value.
 // R2: growable array.
+// R3: current thread.
 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
   __ SetupDartSP(kTestStackSpace);
   __ TagAndPushPP();
   __ LoadPoolPointer(PP);
+  __ Push(THR);
   __ Push(CTX);
   __ Push(LR);
   __ mov(CTX, R0);
+  __ mov(THR, R3);
   __ StoreIntoObject(R2,
                      FieldAddress(R2, GrowableObjectArray::data_offset()),
                      R1);
   __ Pop(LR);
   __ Pop(CTX);
+  __ Pop(THR);
   __ PopAndUntagPP();
   __ mov(CSP, SP);
   __ ret();
diff --git a/runtime/vm/assembler_arm_test.cc b/runtime/vm/assembler_arm_test.cc
index a529214..2cc40fd 100644
--- a/runtime/vm/assembler_arm_test.cc
+++ b/runtime/vm/assembler_arm_test.cc
@@ -3931,13 +3931,15 @@
 // R0: context.
 // R1: value.
 // R2: growable array.
+// R3: current thread.
 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
-  __ PushList((1 << CTX) | (1 << LR));
+  __ PushList((1 << CTX) | (1 << LR) | (1 << THR));
   __ mov(CTX, Operand(R0));
+  __ mov(THR, Operand(R3));
   __ StoreIntoObject(R2,
                      FieldAddress(R2, GrowableObjectArray::data_offset()),
                      R1);
-  __ PopList((1 << CTX) | (1 << LR));
+  __ PopList((1 << CTX) | (1 << LR) | (1 << THR));
   __ Ret();
 }
 
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index d876feb..6ccb225 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -9,6 +9,7 @@
 #include "vm/code_generator.h"
 #include "vm/cpu.h"
 #include "vm/heap.h"
+#include "vm/instructions.h"
 #include "vm/memory_region.h"
 #include "vm/runtime_entry.h"
 #include "vm/stack_frame.h"
@@ -2124,7 +2125,7 @@
 
 
 void Assembler::LoadIsolate(Register dst) {
-  movl(dst, Immediate(reinterpret_cast<uword>(Isolate::Current())));
+  movl(dst, Address(THR, Thread::isolate_offset()));
 }
 
 
@@ -2489,10 +2490,18 @@
 
 void Assembler::EnterFrame(intptr_t frame_size) {
   if (prologue_offset_ == -1) {
+    Comment("PrologueOffset = %" Pd "", CodeSize());
     prologue_offset_ = CodeSize();
   }
+#ifdef DEBUG
+  intptr_t check_offset = CodeSize();
+#endif
   pushl(EBP);
   movl(EBP, ESP);
+#ifdef DEBUG
+  ProloguePattern pp(CodeAddress(check_offset));
+  ASSERT(pp.IsValid());
+#endif
   if (frame_size != 0) {
     Immediate frame_space(frame_size);
     subl(ESP, frame_space);
@@ -2792,6 +2801,10 @@
 // allocate.
 void Assembler::EnterOsrFrame(intptr_t extra_size) {
   Comment("EnterOsrFrame");
+  if (prologue_offset_ == -1) {
+    Comment("PrologueOffset = %" Pd "", CodeSize());
+    prologue_offset_ = CodeSize();
+  }
   Label dart_entry;
   call(&dart_entry);
   Bind(&dart_entry);
diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h
index e00528a..5c0ec98 100644
--- a/runtime/vm/assembler_ia32.h
+++ b/runtime/vm/assembler_ia32.h
@@ -789,6 +789,11 @@
   void Bind(Label* label);
   void Jump(Label* label) { jmp(label); }
 
+  // Address of code at offset.
+  uword CodeAddress(intptr_t offset) {
+    return buffer_.Address(offset);
+  }
+
   intptr_t CodeSize() const { return buffer_.Size(); }
   intptr_t prologue_offset() const { return prologue_offset_; }
 
@@ -848,6 +853,7 @@
   //   pushl immediate(0)
   //   .....
   void EnterStubFrame();
+  static const intptr_t kEnterStubFramePushedWords = 2;
 
   // Instruction pattern from entrypoint is used in dart frame prologs
   // to set up the frame and save a PC which can be used to figure out the
diff --git a/runtime/vm/assembler_ia32_test.cc b/runtime/vm/assembler_ia32_test.cc
index 2fd2866..b541574 100644
--- a/runtime/vm/assembler_ia32_test.cc
+++ b/runtime/vm/assembler_ia32_test.cc
@@ -3393,16 +3393,19 @@
 
 // Called from assembler_test.cc.
 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
+  __ pushl(THR);
   __ pushl(CTX);
-  __ movl(CTX, Address(ESP, 2 * kWordSize));
-  __ movl(EAX, Address(ESP, 3 * kWordSize));
-  __ movl(ECX, Address(ESP, 4 * kWordSize));
+  __ movl(CTX, Address(ESP, 3 * kWordSize));
+  __ movl(EAX, Address(ESP, 4 * kWordSize));
+  __ movl(ECX, Address(ESP, 5 * kWordSize));
+  __ movl(THR, Address(ESP, 6 * kWordSize));
   __ pushl(EAX);
   __ StoreIntoObject(ECX,
                      FieldAddress(ECX, GrowableObjectArray::data_offset()),
                      EAX);
   __ popl(EAX);
   __ popl(CTX);
+  __ popl(THR);
   __ ret();
 }
 
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index 292e140..ef1857c 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -626,7 +626,7 @@
 
 
 void Assembler::LoadIsolate(Register result) {
-  LoadImmediate(result, reinterpret_cast<uword>(Isolate::Current()));
+  lw(result, Address(THR, Thread::isolate_offset()));
 }
 
 
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index d382503..a0a3a41 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -2086,18 +2086,21 @@
 // A0: context.
 // A1: value.
 // A2: growable array.
+// A3: current thread.
 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
-  __ addiu(SP, SP, Immediate(-2 * kWordSize));
+  __ addiu(SP, SP, Immediate(-3 * kWordSize));
+  __ sw(THR, Address(SP, 2 * kWordSize));
   __ sw(CTX, Address(SP, 1 * kWordSize));
   __ sw(RA, Address(SP, 0 * kWordSize));
-
   __ mov(CTX, A0);
+  __ mov(THR, A3);
   __ StoreIntoObject(A2,
                      FieldAddress(A2, GrowableObjectArray::data_offset()),
                      A1);
   __ lw(RA, Address(SP, 0 * kWordSize));
   __ lw(CTX, Address(SP, 1 * kWordSize));
-  __ addiu(SP, SP, Immediate(2 * kWordSize));
+  __ lw(THR, Address(SP, 2 * kWordSize));
+  __ addiu(SP, SP, Immediate(3 * kWordSize));
   __ Ret();
 }
 
diff --git a/runtime/vm/assembler_test.cc b/runtime/vm/assembler_test.cc
index 534d474..088e48c 100644
--- a/runtime/vm/assembler_test.cc
+++ b/runtime/vm/assembler_test.cc
@@ -15,17 +15,18 @@
 
 ASSEMBLER_TEST_RUN(StoreIntoObject, test) {
 #if defined(USING_SIMULATOR)
-#define test_code(ctx, value, growable_array)                                  \
+#define test_code(ctx, value, growable_array, thread)                          \
   Simulator::Current()->Call(                                                  \
       bit_cast<intptr_t, uword>(test->entry()),                                \
       reinterpret_cast<intptr_t>(ctx),                                         \
       reinterpret_cast<intptr_t>(value),                                       \
       reinterpret_cast<intptr_t>(growable_array),                              \
-      0)
+      reinterpret_cast<intptr_t>(thread))
 #else
   typedef void (*StoreData)(RawContext* ctx,
                             RawObject* value,
-                            RawObject* growable_array);
+                            RawObject* growable_array,
+                            Thread* thread);
   StoreData test_code = reinterpret_cast<StoreData>(test->entry());
 #endif
 
@@ -37,6 +38,7 @@
       GrowableObjectArray::New(old_array, Heap::kNew));
   Smi& smi = Smi::Handle();
   const Context& ctx = Context::Handle(Context::New(0));
+  Thread* thread = Thread::Current();
 
   EXPECT(old_array.raw() == grow_old_array.data());
   EXPECT(!Isolate::Current()->store_buffer()->Contains(grow_old_array.raw()));
@@ -46,28 +48,28 @@
   // Store Smis into the old object.
   for (int i = -128; i < 128; i++) {
     smi = Smi::New(i);
-    test_code(ctx.raw(), smi.raw(), grow_old_array.raw());
+    test_code(ctx.raw(), smi.raw(), grow_old_array.raw(), thread);
     EXPECT(reinterpret_cast<RawArray*>(smi.raw()) == grow_old_array.data());
     EXPECT(!Isolate::Current()->store_buffer()->Contains(grow_old_array.raw()));
   }
 
   // Store an old object into the old object.
-  test_code(ctx.raw(), old_array.raw(), grow_old_array.raw());
+  test_code(ctx.raw(), old_array.raw(), grow_old_array.raw(), thread);
   EXPECT(old_array.raw() == grow_old_array.data());
   EXPECT(!Isolate::Current()->store_buffer()->Contains(grow_old_array.raw()));
 
   // Store a new object into the old object.
-  test_code(ctx.raw(), new_array.raw(), grow_old_array.raw());
+  test_code(ctx.raw(), new_array.raw(), grow_old_array.raw(), thread);
   EXPECT(new_array.raw() == grow_old_array.data());
   EXPECT(Isolate::Current()->store_buffer()->Contains(grow_old_array.raw()));
 
   // Store a new object into the new object.
-  test_code(ctx.raw(), new_array.raw(), grow_new_array.raw());
+  test_code(ctx.raw(), new_array.raw(), grow_new_array.raw(), thread);
   EXPECT(new_array.raw() == grow_new_array.data());
   EXPECT(!Isolate::Current()->store_buffer()->Contains(grow_new_array.raw()));
 
   // Store an old object into the new object.
-  test_code(ctx.raw(), old_array.raw(), grow_new_array.raw());
+  test_code(ctx.raw(), old_array.raw(), grow_new_array.raw(), thread);
   EXPECT(old_array.raw() == grow_new_array.data());
   EXPECT(!Isolate::Current()->store_buffer()->Contains(grow_new_array.raw()));
 }
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 45a0754..660c047 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -2810,7 +2810,7 @@
 
 
 void Assembler::LoadIsolate(Register dst) {
-  movq(dst, Immediate(reinterpret_cast<uword>(Isolate::Current())));
+  movq(dst, Address(THR, Thread::isolate_offset()));
 }
 
 
@@ -3224,9 +3224,17 @@
 void Assembler::EnterFrame(intptr_t frame_size) {
   if (prologue_offset_ == -1) {
     prologue_offset_ = CodeSize();
+    Comment("PrologueOffset = %" Pd "", CodeSize());
   }
+#ifdef DEBUG
+  intptr_t check_offset = CodeSize();
+#endif
   pushq(RBP);
   movq(RBP, RSP);
+#ifdef DEBUG
+  ProloguePattern pp(CodeAddress(check_offset));
+  ASSERT(pp.IsValid());
+#endif
   if (frame_size != 0) {
     Immediate frame_space(frame_size);
     subq(RSP, frame_space);
@@ -3406,6 +3414,10 @@
 void Assembler::EnterOsrFrame(intptr_t extra_size,
                               Register new_pp,
                               Register pc_marker_override) {
+  if (prologue_offset_ == -1) {
+    Comment("PrologueOffset = %" Pd "", CodeSize());
+    prologue_offset_ = CodeSize();
+  }
   movq(Address(RBP, kPcMarkerSlotFromFp * kWordSize), pc_marker_override);
   movq(PP, new_pp);
   if (extra_size != 0) {
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index a257d77..4bf6a57 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -885,6 +885,11 @@
 
   const Code::Comments& GetCodeComments() const;
 
+  // Address of code at offset.
+  uword CodeAddress(intptr_t offset) {
+    return buffer_.Address(offset);
+  }
+
   intptr_t CodeSize() const { return buffer_.Size(); }
   intptr_t prologue_offset() const { return prologue_offset_; }
 
diff --git a/runtime/vm/assembler_x64_test.cc b/runtime/vm/assembler_x64_test.cc
index 9989e3b..a10b52e 100644
--- a/runtime/vm/assembler_x64_test.cc
+++ b/runtime/vm/assembler_x64_test.cc
@@ -3308,6 +3308,8 @@
 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
   __ pushq(PP);  // Save caller's pool pointer and load a new one here.
   __ LoadPoolPointer(PP);
+  __ pushq(THR);
+  __ movq(THR, CallingConventions::kArg4Reg);
   __ pushq(CTX);
   __ movq(CTX, CallingConventions::kArg1Reg);
   __ StoreIntoObject(CallingConventions::kArg3Reg,
@@ -3315,6 +3317,7 @@
                                   GrowableObjectArray::data_offset()),
                      CallingConventions::kArg2Reg);
   __ popq(CTX);
+  __ popq(THR);
   __ popq(PP);  // Restore caller's pool pointer.
   __ ret();
 }
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index c76ea3a..b844d01 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -70,7 +70,7 @@
   INIT_LIBRARY(ObjectStore::kProfiler,
                profiler,
                Bootstrap::profiler_source_paths_,
-               Bootstrap::profiler_patch_paths_),
+               NULL),
   INIT_LIBRARY(ObjectStore::kTypedData,
                typed_data,
                Bootstrap::typed_data_source_paths_,
@@ -234,10 +234,10 @@
     patch_file_uri = String::New(patch_files[j]);
     source = GetLibrarySource(lib, patch_file_uri, true);
     if (source.IsNull()) {
-      return Api::UnwrapErrorHandle(
-          isolate,
-          Api::NewError("Unable to find dart patch source for %s",
-                        patch_file_uri.ToCString())).raw();
+      const String& message = String::Handle(
+          String::NewFormatted("Unable to find dart patch source for %s",
+                               patch_file_uri.ToCString()));
+      return ApiError::New(message);
     }
     // Prepend the patch library URI to form a unique script URI for the patch.
     strings.SetAt(2, patch_file_uri);
@@ -292,9 +292,10 @@
     ASSERT(!lib.IsNull());
     source = GetLibrarySource(lib, uri, false);
     if (source.IsNull()) {
-      error ^= Api::UnwrapErrorHandle(
-          isolate, Api::NewError("Unable to find dart source for %s",
-                                 uri.ToCString())).raw();
+      const String& message = String::Handle(
+          String::NewFormatted("Unable to find dart source for %s",
+                               uri.ToCString()));
+      error ^= ApiError::New(message);
       break;
     }
     script = Script::New(uri, source, RawScript::kLibraryTag);
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 23c0d52..78d4539 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1165,7 +1165,7 @@
       AbstractType::Handle(FinalizeType(cls, type, kCanonicalize));
   // The result type may be malformed or malbounded.
   if (type.raw() != finalized_type.raw()) {
-    function.set_result_type(type);
+    function.set_result_type(finalized_type);
   }
   // Resolve formal parameter types.
   const intptr_t num_parameters = function.NumParameters();
@@ -1174,7 +1174,7 @@
     finalized_type = FinalizeType(cls, type, kCanonicalize);
     // The parameter type may be malformed or malbounded.
     if (type.raw() != finalized_type.raw()) {
-      function.SetParameterTypeAt(i, type);
+      function.SetParameterTypeAt(i, finalized_type);
     }
   }
 }
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 666b13c..2e7df3b 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -630,7 +630,7 @@
 DEFINE_RUNTIME_ENTRY(Throw, 1) {
   const Instance& exception =
       Instance::CheckedHandle(zone, arguments.ArgAt(0));
-  Exceptions::Throw(isolate, exception);
+  Exceptions::Throw(thread, exception);
 }
 
 
@@ -639,7 +639,7 @@
       Instance::CheckedHandle(zone, arguments.ArgAt(0));
   const Instance& stacktrace =
       Instance::CheckedHandle(zone, arguments.ArgAt(1));
-  Exceptions::ReThrow(isolate, exception, stacktrace);
+  Exceptions::ReThrow(thread, exception, stacktrace);
 }
 
 
@@ -1125,7 +1125,7 @@
     // into dart code.
     const Instance& exception =
         Instance::Handle(isolate->object_store()->stack_overflow());
-    Exceptions::Throw(isolate, exception);
+    Exceptions::Throw(thread, exception);
     UNREACHABLE();
   }
 
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 892a2f9..7ff3ed9 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -721,13 +721,13 @@
         const Array& intervals = graph_compiler.inlined_code_intervals();
         INC_STAT(isolate, total_code_size,
                  intervals.Length() * sizeof(uword));
-        code.set_inlined_intervals(intervals);
+        code.SetInlinedIntervals(intervals);
 
         const Array& inlined_id_array =
             Array::Handle(isolate, graph_compiler.InliningIdToFunction());
         INC_STAT(isolate, total_code_size,
                  inlined_id_array.Length() * sizeof(uword));
-        code.set_inlined_id_to_function(inlined_id_array);
+        code.SetInlinedIdToFunction(inlined_id_array);
 
         graph_compiler.FinalizePcDescriptors(code);
         code.set_deopt_info_array(deopt_info_array);
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 322676c..c4487b6 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -238,6 +238,7 @@
 const Register LRREG = LR;  // Link register.
 const Register ICREG = R5;  // IC data register.
 const Register ARGS_DESC_REG = R4;
+const Register THR = R8;  // Caches current thread in generated code.
 
 // R15 encodes APSR in the vmrs instruction.
 const Register APSR = R15;
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 2d74ef3..f1834b8 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -117,6 +117,7 @@
 const Register LRREG = LR;  // Link register.
 const Register ICREG = R5;  // IC data register.
 const Register ARGS_DESC_REG = R4;  // Arguments descriptor register.
+const Register THR = R20;  // Caches current thread in generated code.
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index d609b8a..f1edc35 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -68,6 +68,7 @@
 const Register FPREG = EBP;  // Frame pointer register.
 const Register ICREG = ECX;  // IC data register.
 const Register ARGS_DESC_REG = EDX;  // Arguments descriptor register.
+const Register THR = ESI;  // Caches current thread in generated code.
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index e9a76a4..5c721b3 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -185,6 +185,7 @@
 const Register LRREG = RA;  // Link register.
 const Register ICREG = S5;  // IC data register.
 const Register ARGS_DESC_REG = S4;
+const Register THR = S3;  // Caches current thread in generated code.
 
 // The code that generates a comparison can be far away from the code that
 // generates the branch that uses the result of that comparison. In this case,
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index d42687e..fdded5f 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -86,13 +86,14 @@
 // Register aliases.
 const Register TMP = R11;  // Used as scratch register by the assembler.
 const Register TMP2 = kNoRegister;  // No second assembler scratch register.
-const Register CTX = R14;  // Location of current context at method entry.
+const Register CTX = R9;  // Location of current context at method entry.
 // Caches object pool pointer in generated code.
 const Register PP = R15;
 const Register SPREG = RSP;  // Stack pointer register.
 const Register FPREG = RBP;  // Frame pointer register.
 const Register ICREG = RBX;  // IC data register.
 const Register ARGS_DESC_REG = R10;  // Arguments descriptor register.
+const Register THR = R14;  // Caches current thread in generated code.
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
diff --git a/runtime/vm/coverage_test.cc b/runtime/vm/coverage_test.cc
index 2301d3a..92a98cd 100644
--- a/runtime/vm/coverage_test.cc
+++ b/runtime/vm/coverage_test.cc
@@ -50,9 +50,9 @@
   char buf[1024];
   OS::SNPrint(buf, sizeof(buf),
       "{\"source\":\"test-lib\",\"script\":{\"type\":\"@Script\","
-      "\"id\":\"libraries\\/%" Pd  "\\/scripts\\/test-lib\","
-      "\"name\":\"test-lib\","
-      "\"kind\":\"script\"},\"hits\":[]}", lib.index());
+      "\"fixedId\":true,\"id\":\"libraries\\/%" Pd  "\\/scripts\\/test-lib\","
+      "\"uri\":\"test-lib\","
+      "\"_kind\":\"script\"},\"hits\":[]}", lib.index());
   EXPECT_SUBSTRING(buf, js.ToCString());
 }
 
@@ -87,17 +87,17 @@
   // Data for the actual class Foo.
   OS::SNPrint(buf, sizeof(buf),
       "{\"source\":\"test-lib\",\"script\":{\"type\":\"@Script\","
-      "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\","
-      "\"name\":\"test-lib\","
-      "\"kind\":\"script\"},\"hits\":[3,1,5,4,6,3]}", lib.index());
+      "\"fixedId\":true,\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\","
+      "\"uri\":\"test-lib\","
+      "\"_kind\":\"script\"},\"hits\":[3,1,5,4,6,3]}", lib.index());
   EXPECT_SUBSTRING(buf, js.ToCString());
 
   // Data for the fake class containing main().
   OS::SNPrint(buf, sizeof(buf),
       "{\"source\":\"test-lib\",\"script\":{\"type\":\"@Script\","
-      "\"id\":\"libraries\\/%" Pd  "\\/scripts\\/test-lib\","
-      "\"name\":\"test-lib\","
-      "\"kind\":\"script\"},\"hits\":[10,1,11,1]}", lib.index());
+      "\"fixedId\":true,\"id\":\"libraries\\/%" Pd  "\\/scripts\\/test-lib\","
+      "\"uri\":\"test-lib\","
+      "\"_kind\":\"script\"},\"hits\":[10,1,11,1]}", lib.index());
   EXPECT_SUBSTRING(buf, js.ToCString());
 }
 
@@ -133,9 +133,9 @@
   char buf[1024];
   OS::SNPrint(buf, sizeof(buf),
       "{\"source\":\"test-lib\",\"script\":{\"type\":\"@Script\","
-      "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\","
-      "\"name\":\"test-lib\","
-      "\"kind\":\"script\"},\"hits\":[6,0]}", lib.index());
+      "\"fixedId\":true,\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\","
+      "\"uri\":\"test-lib\","
+      "\"_kind\":\"script\"},\"hits\":[6,0]}", lib.index());
   EXPECT_SUBSTRING(buf, js.ToCString());
 }
 
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index d14ba97..4b6b5fb 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -156,7 +156,6 @@
         OS::Print("VM Isolate: Number of symbols : %" Pd "\n", size);
         OS::Print("VM Isolate: Symbol table capacity : %" Pd "\n", capacity);
       }
-      Symbols::InitOnceFromSnapshot(vm_isolate_);
     } else {
       Symbols::InitOnce(vm_isolate_);
     }
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index a6feef0..a913a12 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -43,6 +43,7 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, load_deferred_eagerly);
 DECLARE_FLAG(bool, print_class_table);
 DECLARE_FLAG(bool, verify_handles);
 #if defined(DART_NO_SNAPSHOT)
@@ -120,7 +121,7 @@
     *str = NULL;
     return true;
   }
-  Isolate* isolate = arguments->isolate();
+  Isolate* isolate = arguments->thread()->isolate();
   ASSERT(isolate == Isolate::Current());
   *peer = NULL;
   REUSABLE_OBJECT_HANDLESCOPE(isolate);
@@ -147,7 +148,7 @@
   if (Api::GetNativeIntegerArgument(arguments, arg_index, value)) {
     return true;
   }
-  Isolate* isolate = arguments->isolate();
+  Isolate* isolate = arguments->thread()->isolate();
   ASSERT(isolate == Isolate::Current());
   REUSABLE_OBJECT_HANDLESCOPE(isolate);
   Object& obj = isolate->ObjectHandle();
@@ -173,7 +174,7 @@
     *value = static_cast<uint64_t>(arg_value);
     return true;
   }
-  Isolate* isolate = arguments->isolate();
+  Isolate* isolate = arguments->thread()->isolate();
   ASSERT(isolate == Isolate::Current());
   REUSABLE_OBJECT_HANDLESCOPE(isolate);
   Object& obj = isolate->ObjectHandle();
@@ -197,7 +198,7 @@
   if (Api::GetNativeDoubleArgument(arguments, arg_index, value)) {
     return true;
   }
-  Isolate* isolate = arguments->isolate();
+  Isolate* isolate = arguments->thread()->isolate();
   ASSERT(isolate == Isolate::Current());
   REUSABLE_OBJECT_HANDLESCOPE(isolate);
   Object& obj = isolate->ObjectHandle();
@@ -223,7 +224,7 @@
                                      field_values)) {
     return Api::Success();
   }
-  Isolate* isolate = arguments->isolate();
+  Isolate* isolate = arguments->thread()->isolate();
   ASSERT(isolate == Isolate::Current());
   REUSABLE_OBJECT_HANDLESCOPE(isolate);
   Object& obj = isolate->ObjectHandle();
@@ -488,7 +489,7 @@
     return true;
   }
   if (cid == kOneByteStringCid || cid == kTwoByteStringCid) {
-    Isolate* isolate = arguments->isolate();
+    Isolate* isolate = arguments->thread()->isolate();
     *peer = isolate->heap()->GetPeer(raw_obj);
     return (*peer != 0);
   }
@@ -1293,23 +1294,28 @@
   Thread::EnsureInit();
   Isolate* isolate = Dart::CreateIsolate(isolate_name);
   free(isolate_name);
-  {
-    StackZone zone(isolate);
-    HANDLESCOPE(isolate);
-    const Error& error_obj =
-        Error::Handle(isolate,
-                      Dart::InitializeIsolate(snapshot, callback_data));
-    if (error_obj.IsNull()) {
+  StackZone zone(isolate);
+  HANDLESCOPE(isolate);
+  // We enter an API scope here as InitializeIsolate could compile some
+  // 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(isolate, Dart::InitializeIsolate(snapshot, callback_data));
+  if (error_obj.IsNull()) {
 #if defined(DART_NO_SNAPSHOT)
-      if (FLAG_check_function_fingerprints) {
-        Library::CheckFunctionFingerprints();
-      }
-#endif  // defined(DART_NO_SNAPSHOT).
-      START_TIMER(isolate, time_total_runtime);
-      return reinterpret_cast<Dart_Isolate>(isolate);
+    if (FLAG_check_function_fingerprints) {
+      Library::CheckFunctionFingerprints();
     }
-    *error = strdup(error_obj.ToErrorCString());
+#endif  // defined(DART_NO_SNAPSHOT).
+    // We exit the API scope entered above.
+    Dart_ExitScope();
+    START_TIMER(isolate, time_total_runtime);
+    return Api::CastIsolate(isolate);
   }
+  *error = strdup(error_obj.ToErrorCString());
+  // We exit the API scope entered above.
+  Dart_ExitScope();
   Dart::ShutdownIsolate();
   return reinterpret_cast<Dart_Isolate>(NULL);
 }
@@ -1424,6 +1430,7 @@
     intptr_t* vm_isolate_snapshot_size,
     uint8_t** isolate_snapshot_buffer,
     intptr_t* isolate_snapshot_size) {
+  ASSERT(FLAG_load_deferred_eagerly);
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   TIMERSCOPE(isolate, time_creating_snapshot);
@@ -2702,7 +2709,8 @@
 
 
 static RawObject* ThrowArgumentError(const char* exception_message) {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   // Lookup the class ArgumentError in dart:core.
   const String& lib_url = String::Handle(String::New("dart:core"));
   const String& class_name = String::Handle(String::New("ArgumentError"));
@@ -2760,7 +2768,7 @@
     state->UnwindScopes(isolate->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
   }
-  Exceptions::Throw(isolate, *saved_exception);
+  Exceptions::Throw(thread, *saved_exception);
   const String& message = String::Handle(
           String::New("Exception was not thrown, internal error"));
   return ApiError::New(message);
@@ -4432,7 +4440,8 @@
 // --- Exceptions ----
 
 DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
   CHECK_CALLBACK_STATE(isolate);
   {
@@ -4459,14 +4468,15 @@
     state->UnwindScopes(isolate->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
   }
-  Exceptions::Throw(isolate, *saved_exception);
+  Exceptions::Throw(thread, *saved_exception);
   return Api::NewError("Exception was not thrown, internal error");
 }
 
 
 DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception,
                                               Dart_Handle stacktrace) {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
   CHECK_CALLBACK_STATE(isolate);
   {
@@ -4501,7 +4511,7 @@
     saved_exception = &Instance::Handle(raw_exception);
     saved_stacktrace = &Stacktrace::Handle(raw_stacktrace);
   }
-  Exceptions::ReThrow(isolate, *saved_exception, *saved_stacktrace);
+  Exceptions::ReThrow(thread, *saved_exception, *saved_stacktrace);
   return Api::NewError("Exception was not re thrown, internal error");
 }
 
@@ -4593,7 +4603,7 @@
 
 DART_EXPORT void* Dart_GetNativeIsolateData(Dart_NativeArguments args) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-  Isolate* isolate = arguments->isolate();
+  Isolate* isolate = arguments->thread()->isolate();
   ASSERT(isolate == Isolate::Current());
   return isolate->init_callback_data();
 }
@@ -4605,7 +4615,7 @@
     const Dart_NativeArgument_Descriptor* argument_descriptors,
     Dart_NativeArgument_Value* arg_values) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-  ASSERT(arguments->isolate() == Isolate::Current());
+  ASSERT(arguments->thread()->isolate() == Isolate::Current());
   if (arg_values == NULL) {
     RETURN_NULL_ERROR(arg_values);
   }
@@ -4715,7 +4725,7 @@
       }
 
       case Dart_NativeArgument_kInstance: {
-        Isolate* isolate = arguments->isolate();
+        Isolate* isolate = arguments->thread()->isolate();
         ASSERT(isolate == Isolate::Current());
         ASSERT(isolate->api_state() &&
                isolate->api_state()->top_scope() != NULL);
@@ -4742,7 +4752,8 @@
         "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
         CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
   }
-  return Api::NewHandle(arguments->isolate(), arguments->NativeArgAt(index));
+  return Api::NewHandle(arguments->thread()->isolate(),
+                        arguments->NativeArgAt(index));
 }
 
 
@@ -4778,7 +4789,7 @@
 DART_EXPORT Dart_Handle Dart_GetNativeReceiver(Dart_NativeArguments args,
                                                intptr_t* value) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-  ASSERT(arguments->isolate() == Isolate::Current());
+  ASSERT(arguments->thread()->isolate() == Isolate::Current());
   if (value == NULL) {
     RETURN_NULL_ERROR(value);
   }
@@ -4860,7 +4871,7 @@
 DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args,
                                      Dart_Handle retval) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-  ASSERT(arguments->isolate() == Isolate::Current());
+  ASSERT(arguments->thread()->isolate() == Isolate::Current());
   if ((retval != Api::Null()) && (!Api::IsInstance(retval))) {
     const Object& ret_obj = Object::Handle(Api::UnwrapHandle(retval));
     FATAL1("Return value check failed: saw '%s' expected a dart Instance.",
@@ -4875,7 +4886,7 @@
                                                Dart_WeakPersistentHandle rval) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
 #if defined(DEBUG)
-  Isolate* isolate = arguments->isolate();
+  Isolate* isolate = arguments->thread()->isolate();
   ASSERT(isolate == Isolate::Current());
   ASSERT(isolate->api_state() != NULL &&
          (isolate->api_state()->IsValidWeakPersistentHandle(rval) ||
@@ -4939,12 +4950,12 @@
 DART_EXPORT void Dart_SetIntegerReturnValue(Dart_NativeArguments args,
                                             int64_t retval) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-  ASSERT(arguments->isolate() == Isolate::Current());
+  ASSERT(arguments->thread()->isolate() == Isolate::Current());
   if (Smi::IsValid(retval)) {
     Api::SetSmiReturnValue(arguments, static_cast<intptr_t>(retval));
   } else {
     // Slow path for Mints and Bigints.
-    ASSERT_CALLBACK_STATE(arguments->isolate());
+    ASSERT_CALLBACK_STATE(arguments->thread()->isolate());
     Api::SetIntegerReturnValue(arguments, retval);
   }
 }
@@ -4954,7 +4965,7 @@
                                            double retval) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
 #if defined(DEBUG)
-  Isolate* isolate = arguments->isolate();
+  Isolate* isolate = arguments->thread()->isolate();
   ASSERT(isolate == Isolate::Current());
   ASSERT_CALLBACK_STATE(isolate);
 #endif
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 2c0cf34..540434a 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -19,6 +19,7 @@
     : BaseReader(buffer, length),
       alloc_(alloc),
       backward_references_(kNumInitialReferences),
+      vm_isolate_references_(kNumInitialReferences),
       vm_symbol_references_(NULL),
       max_vm_isolate_object_id_(
           use_vm_isolate_snapshot ?
@@ -200,7 +201,41 @@
 
 
 Dart_CObject* ApiMessageReader::AllocateDartCObjectVmIsolateObj(intptr_t id) {
-  return CreateDartCObjectString(VmIsolateSnapshotObject(id));
+  RawObject* raw = VmIsolateSnapshotObject(id);
+  intptr_t cid = raw->GetClassId();
+  switch (cid) {
+    case kOneByteStringCid: {
+      RawOneByteString* raw_str = reinterpret_cast<RawOneByteString*>(raw);
+      const char* str = reinterpret_cast<const char*>(raw_str->ptr()->data());
+      ASSERT(str != NULL);
+      Dart_CObject* object = NULL;
+      for (intptr_t i = 0; i < vm_isolate_references_.length(); i++) {
+        object = vm_isolate_references_.At(i);
+        if (object->type == Dart_CObject_kString) {
+          if (strcmp(str, const_cast<char*>(object->value.as_string)) == 0) {
+            return object;
+          }
+        }
+      }
+      object = CreateDartCObjectString(raw);
+      vm_isolate_references_.Add(object);
+      return object;
+    }
+
+    case kMintCid: {
+      const Mint& obj = Mint::Handle(reinterpret_cast<RawMint*>(raw));
+      int64_t value64 = obj.value();
+      if ((kMinInt32 <= value64) && (value64 <= kMaxInt32)) {
+        return GetCanonicalMintObject(Dart_CObject_kInt32, value64);
+      } else {
+        return GetCanonicalMintObject(Dart_CObject_kInt64, value64);
+      }
+    }
+
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
 }
 
 
@@ -403,6 +438,27 @@
 }
 
 
+Dart_CObject* ApiMessageReader::GetCanonicalMintObject(Dart_CObject_Type type,
+                                                       int64_t value64) {
+  Dart_CObject* object = NULL;
+  for (intptr_t i = 0; i < vm_isolate_references_.length(); i++) {
+    object = vm_isolate_references_.At(i);
+    if (object->type == type) {
+      if (value64 == object->value.as_int64) {
+        return object;
+      }
+    }
+  }
+  if (type == Dart_CObject_kInt32) {
+    object = AllocateDartCObjectInt32(static_cast<int32_t>(value64));
+  } else {
+    object = AllocateDartCObjectInt64(value64);
+  }
+  vm_isolate_references_.Add(object);
+  return object;
+}
+
+
 Dart_CObject* ApiMessageReader::ReadObjectRef() {
   int64_t value64 = Read<int64_t>();
   if ((value64 & kSmiTagMask) == 0) {
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index 302b463..8d38364 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -137,12 +137,15 @@
   }
 
   Dart_CObject* CreateDartCObjectString(RawObject* raw);
+  Dart_CObject* GetCanonicalMintObject(Dart_CObject_Type type,
+                                       int64_t value64);
 
   // Allocation of the structures for the decoded message happens
   // either in the supplied zone or using the supplied allocation
   // function.
   ReAlloc alloc_;
   ApiGrowableArray<BackRefNode*> backward_references_;
+  ApiGrowableArray<Dart_CObject*> vm_isolate_references_;
   Dart_CObject** vm_symbol_references_;
   intptr_t max_vm_isolate_object_id_;
 
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index fd1c9de..10c194b 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -105,19 +105,20 @@
         static_cast<int64_t>(code.EntryPoint()),
         reinterpret_cast<int64_t>(&arguments_descriptor),
         reinterpret_cast<int64_t>(&arguments),
-        0));
+        reinterpret_cast<int64_t>(thread)));
 #else
     return bit_copy<RawObject*, int64_t>(Simulator::Current()->Call(
         reinterpret_cast<int32_t>(entrypoint),
         static_cast<int32_t>(code.EntryPoint()),
         reinterpret_cast<int32_t>(&arguments_descriptor),
         reinterpret_cast<int32_t>(&arguments),
-        0));
+        reinterpret_cast<int32_t>(thread)));
 #endif
 #else
     return entrypoint(code.EntryPoint(),
                       arguments_descriptor,
-                      arguments);
+                      arguments,
+                      thread);
 #endif
 }
 
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index d8e86af..f88a416 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -102,7 +102,8 @@
   // On success, returns a RawInstance.  On failure, a RawError.
   typedef RawObject* (*invokestub)(uword entry_point,
                                    const Array& arguments_descriptor,
-                                   const Array& arguments);
+                                   const Array& arguments,
+                                   Thread* thread);
 
   // Invokes the specified instance function or static function.
   // The first argument of an instance function is the receiver.
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 60059ee..516caf7 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -25,6 +25,7 @@
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
+#include "vm/thread_interrupter.h"
 #include "vm/visitor.h"
 
 
@@ -62,58 +63,54 @@
 
 
 // Create an unresolved breakpoint in given token range and script.
-SourceBreakpoint::SourceBreakpoint(intptr_t id,
-                                   const Script& script,
-                                   intptr_t token_pos,
-                                   intptr_t end_token_pos)
-    : id_(id),
-      script_(script.raw()),
+BreakpointLocation::BreakpointLocation(const Script& script,
+                                       intptr_t token_pos,
+                                       intptr_t end_token_pos)
+    : script_(script.raw()),
       url_(script.url()),
       token_pos_(token_pos),
       end_token_pos_(end_token_pos),
       is_resolved_(false),
-      is_enabled_(false),
-      is_one_shot_(false),
       next_(NULL),
+      conditions_(NULL),
       function_(Function::null()),
       line_number_(-1) {
-  ASSERT(id_ > 0);
   ASSERT(!script.IsNull());
   ASSERT(token_pos_ >= 0);
 }
 
 // Create a latent breakpoint at given url and line number.
-SourceBreakpoint::SourceBreakpoint(intptr_t id,
-                                   const String& url,
-                                   intptr_t line_number)
-    : id_(id),
-      script_(Script::null()),
+BreakpointLocation::BreakpointLocation(const String& url,
+                                       intptr_t line_number)
+    : script_(Script::null()),
       url_(url.raw()),
       token_pos_(-1),
       end_token_pos_(-1),
       is_resolved_(false),
-      is_enabled_(false),
-      is_one_shot_(false),
       next_(NULL),
+      conditions_(NULL),
       function_(Function::null()),
       line_number_(line_number) {
-  ASSERT(id >= 0);
   ASSERT(line_number_ >= 0);
 }
 
-void SourceBreakpoint::Enable() {
-  is_enabled_ = true;
-  Isolate::Current()->debugger()->SyncBreakpoint(this);
+
+BreakpointLocation::~BreakpointLocation() {
+  Breakpoint* bpt = breakpoints();
+  while (bpt != NULL) {
+    Breakpoint* temp = bpt;
+    bpt = bpt->next();
+    delete temp;
+  }
 }
 
 
-void SourceBreakpoint::Disable() {
-  is_enabled_ = false;
-  Isolate::Current()->debugger()->SyncBreakpoint(this);
+bool BreakpointLocation::AnyEnabled() const {
+  return breakpoints() != NULL;
 }
 
 
-void SourceBreakpoint::SetResolved(const Function& func, intptr_t token_pos) {
+void BreakpointLocation::SetResolved(const Function& func, intptr_t token_pos) {
   ASSERT(!IsLatent());
   ASSERT(func.script() == script_);
   ASSERT((func.token_pos() <= token_pos) &&
@@ -130,9 +127,9 @@
 // TODO(hausner): Get rid of library parameter. A source breakpoint location
 // does not imply a library, since the same source code can be included
 // in more than one library, e.g. the text location of mixin functions.
-void SourceBreakpoint::GetCodeLocation(Library* lib,
-                                       Script* script,
-                                       intptr_t* pos) {
+void BreakpointLocation::GetCodeLocation(Library* lib,
+                                         Script* script,
+                                         intptr_t* pos) {
   if (IsLatent()) {
     *lib = Library::null();
     *script = Script::null();
@@ -152,7 +149,7 @@
 }
 
 
-intptr_t SourceBreakpoint::LineNumber() {
+intptr_t BreakpointLocation::LineNumber() {
   // Latent breakpoints must have a requested line number >= 0.
   ASSERT(!IsLatent() || line_number_ >= 0);
   // Compute line number lazily since it causes scanning of the script.
@@ -164,27 +161,44 @@
 }
 
 
-void SourceBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&script_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&url_));
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_));
+void Breakpoint::set_bpt_location(BreakpointLocation* new_bpt_location) {
+  ASSERT(bpt_location_->IsLatent());  // Only reason to move.
+  bpt_location_ = new_bpt_location;
 }
 
 
-void SourceBreakpoint::PrintJSON(JSONStream* stream) {
+void Breakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
+  visitor->VisitPointer(reinterpret_cast<RawObject**>(&closure_));
+}
+
+
+void BreakpointLocation::VisitObjectPointers(ObjectPointerVisitor* visitor) {
+  visitor->VisitPointer(reinterpret_cast<RawObject**>(&script_));
+  visitor->VisitPointer(reinterpret_cast<RawObject**>(&url_));
+  visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_));
+
+  Breakpoint* bpt = conditions_;
+  while (bpt != NULL) {
+    bpt -> VisitObjectPointers(visitor);
+    bpt = bpt->next();
+  }
+}
+
+
+void Breakpoint::PrintJSON(JSONStream* stream) {
   Isolate* isolate = Isolate::Current();
 
   JSONObject jsobj(stream);
   jsobj.AddProperty("type", "Breakpoint");
 
-  jsobj.AddPropertyF("id", "breakpoints/%" Pd "", id());
+  jsobj.AddFixedServiceId("breakpoints/%" Pd "", id());
   jsobj.AddProperty("breakpointNumber", id());
-  jsobj.AddProperty("resolved", IsResolved());
+  jsobj.AddProperty("resolved", bpt_location_->IsResolved());
 
   Library& library = Library::Handle(isolate);
   Script& script = Script::Handle(isolate);
   intptr_t token_pos;
-  GetCodeLocation(&library, &script, &token_pos);
+  bpt_location_->GetCodeLocation(&library, &script, &token_pos);
   {
     JSONObject location(&jsobj, "location");
     location.AddProperty("type", "Location");
@@ -293,7 +307,7 @@
 // The vm service handles breakpoint notifications in a different way
 // than the regular debugger breakpoint notifications.
 static void SendServiceBreakpointEvent(ServiceEvent::EventType type,
-                                       SourceBreakpoint* bpt) {
+                                       Breakpoint* bpt) {
   if (Service::NeedsEvents()) {
     ServiceEvent service_event(Isolate::Current(), type);
     service_event.set_breakpoint(bpt);
@@ -302,6 +316,65 @@
 }
 
 
+void BreakpointLocation::AddBreakpoint(Breakpoint* bpt, Debugger* dbg) {
+  bpt->set_next(breakpoints());
+  set_breakpoints(bpt);
+
+  dbg->SyncBreakpointLocation(this);
+
+  if (IsResolved()) {
+    dbg->SignalBpResolved(bpt);
+  }
+  SendServiceBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt);
+}
+
+
+Breakpoint* BreakpointLocation::AddRepeated(Debugger* dbg) {
+  Breakpoint* bpt = breakpoints();
+  while (bpt != NULL) {
+    if (bpt->IsRepeated()) break;
+    bpt = bpt->next();
+  }
+  if (bpt == NULL) {
+    bpt = new Breakpoint(dbg->nextId(), this);
+    bpt->SetIsRepeated();
+    AddBreakpoint(bpt, dbg);
+  }
+  return bpt;
+}
+
+
+Breakpoint* BreakpointLocation::AddSingleShot(Debugger* dbg) {
+  Breakpoint* bpt = breakpoints();
+  while (bpt != NULL) {
+    if (bpt->IsSingleShot()) break;
+    bpt = bpt->next();
+  }
+  if (bpt == NULL) {
+    bpt = new Breakpoint(dbg->nextId(), this);
+    bpt->SetIsSingleShot();
+    AddBreakpoint(bpt, dbg);
+  }
+  return bpt;
+}
+
+
+Breakpoint* BreakpointLocation::AddPerClosure(Debugger* dbg,
+                                              const Instance& closure) {
+  Breakpoint* bpt = breakpoints();
+  while (bpt != NULL) {
+    if (bpt->IsPerClosure() && bpt->closure() == closure.raw()) break;
+    bpt = bpt->next();
+  }
+  if (bpt == NULL) {
+    bpt = new Breakpoint(dbg->nextId(), this);
+    bpt->SetIsPerClosure(closure);
+    AddBreakpoint(bpt, dbg);
+  }
+  return bpt;
+}
+
+
 const char* Debugger::QualifiedFunctionName(const Function& func) {
   const String& func_name = String::Handle(func.name());
   Class& func_class = Class::Handle(func.Owner());
@@ -342,7 +415,7 @@
     // range of the function. This may be a false positive: the breakpoint
     // might be inside a local closure.
     Script& script = Script::Handle(isolate_);
-    SourceBreakpoint* sbpt = src_breakpoints_;
+    BreakpointLocation* sbpt = breakpoint_locations_;
     while (sbpt != NULL) {
       script = sbpt->script();
       if (FunctionContains(func, script, sbpt->token_pos())) {
@@ -376,9 +449,13 @@
 
 
 void Debugger::PrintBreakpointsToJSONArray(JSONArray* jsarr) const {
-  SourceBreakpoint* sbpt = src_breakpoints_;
+  BreakpointLocation* sbpt = breakpoint_locations_;
   while (sbpt != NULL) {
-    jsarr->AddValue(sbpt);
+    Breakpoint* bpt = sbpt->breakpoints();
+    while (bpt != NULL) {
+      jsarr->AddValue(bpt);
+      bpt = bpt->next();
+    }
     sbpt = sbpt->next_;
   }
 }
@@ -675,6 +752,34 @@
 }
 
 
+RawObject* ActivationFrame::GetParameter(intptr_t index) {
+  intptr_t num_parameters = function().num_fixed_parameters();
+  ASSERT(0 <= index && index < num_parameters);
+  intptr_t reverse_index = num_parameters - index;
+
+  if (function().NumOptionalParameters() > 0) {
+    // If the function has optional parameters, the first positional parameter
+    // can be in a number of places in the caller's frame depending on how many
+    // were actually supplied at the call site, but they are copied to a fixed
+    // place in the callee's frame.
+    uword var_address = fp() + ((kFirstLocalSlotFromFp - index) * kWordSize);
+    return reinterpret_cast<RawObject*>(
+        *reinterpret_cast<uword*>(var_address));
+  } else {
+    uword var_address = fp() + (kParamEndSlotFromFp * kWordSize)
+                             + (reverse_index * kWordSize);
+    return reinterpret_cast<RawObject*>(
+        *reinterpret_cast<uword*>(var_address));
+  }
+}
+
+
+RawObject* ActivationFrame::GetClosure() {
+  ASSERT(function().IsClosureFunction());
+  return GetParameter(0);
+}
+
+
 RawObject* ActivationFrame::GetLocalVar(intptr_t slot_index) {
   if (deopt_frame_.IsNull()) {
     uword var_address = fp() + slot_index * kWordSize;
@@ -945,7 +1050,7 @@
       pc_(pc),
       line_number_(-1),
       is_enabled_(false),
-      src_bpt_(NULL),
+      bpt_location_(NULL),
       next_(NULL),
       breakpoint_kind_(kind),
       saved_value_(0) {
@@ -963,7 +1068,7 @@
 #ifdef DEBUG
   code_ = Code::null();
   pc_ = 0ul;
-  src_bpt_ = NULL;
+  bpt_location_ = NULL;
   next_ = NULL;
   breakpoint_kind_ = RawPcDescriptors::kOther;
 #endif
@@ -1042,8 +1147,8 @@
       isolate_id_(ILLEGAL_ISOLATE_ID),
       initialized_(false),
       next_id_(1),
-      latent_breakpoints_(NULL),
-      src_breakpoints_(NULL),
+      latent_locations_(NULL),
+      breakpoint_locations_(NULL),
       code_breakpoints_(NULL),
       resume_action_(kContinue),
       ignore_breakpoints_(false),
@@ -1058,8 +1163,8 @@
 Debugger::~Debugger() {
   isolate_id_ = ILLEGAL_ISOLATE_ID;
   ASSERT(!IsPaused());
-  ASSERT(latent_breakpoints_ == NULL);
-  ASSERT(src_breakpoints_ == NULL);
+  ASSERT(latent_locations_ == NULL);
+  ASSERT(breakpoint_locations_ == NULL);
   ASSERT(code_breakpoints_ == NULL);
   ASSERT(stack_trace_ == NULL);
   ASSERT(obj_cache_ == NULL);
@@ -1067,14 +1172,14 @@
 
 
 void Debugger::Shutdown() {
-  while (src_breakpoints_ != NULL) {
-    SourceBreakpoint* bpt = src_breakpoints_;
-    src_breakpoints_ = src_breakpoints_->next();
+  while (breakpoint_locations_ != NULL) {
+    BreakpointLocation* bpt = breakpoint_locations_;
+    breakpoint_locations_ = breakpoint_locations_->next();
     delete bpt;
   }
-  while (latent_breakpoints_ != NULL) {
-    SourceBreakpoint* bpt = latent_breakpoints_;
-    latent_breakpoints_ = latent_breakpoints_->next();
+  while (latent_locations_ != NULL) {
+    BreakpointLocation* bpt = latent_locations_;
+    latent_locations_ = latent_locations_->next();
     delete bpt;
   }
   while (code_breakpoints_ != NULL) {
@@ -1192,8 +1297,8 @@
 }
 
 
-void Debugger::SignalBpResolved(SourceBreakpoint* bpt) {
-  if (HasEventHandler() && !bpt->IsOneShot()) {
+void Debugger::SignalBpResolved(Breakpoint* bpt) {
+  if (HasEventHandler() && !bpt->IsSingleShot()) {
     DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved);
     event.set_breakpoint(bpt);
     InvokeEventHandler(&event);
@@ -1511,9 +1616,9 @@
 
 
 void Debugger::MakeCodeBreakpointAt(const Function& func,
-                                    SourceBreakpoint* bpt) {
-  ASSERT(bpt->token_pos_ != Scanner::kNoSourcePos);
-  ASSERT((bpt != NULL) && bpt->IsResolved());
+                                    BreakpointLocation* loc) {
+  ASSERT(loc->token_pos_ != Scanner::kNoSourcePos);
+  ASSERT((loc != NULL) && loc->IsResolved());
   ASSERT(!func.HasOptimizedCode());
   Code& code = Code::Handle(func.unoptimized_code());
   ASSERT(!code.IsNull());
@@ -1524,7 +1629,7 @@
   // that maps to the token position of the source breakpoint.
   PcDescriptors::Iterator iter(desc, kSafepointKind);
   while (iter.MoveNext()) {
-    if (iter.TokenPos() == bpt->token_pos_) {
+    if (iter.TokenPos() == loc->token_pos_) {
       if (iter.PcOffset() < lowest_pc_offset) {
         lowest_pc_offset = iter.PcOffset();
         lowest_kind = iter.Kind();
@@ -1538,12 +1643,12 @@
   CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_pc);
   if (code_bpt == NULL) {
     // No code breakpoint for this code exists; create one.
-    code_bpt = new CodeBreakpoint(code, bpt->token_pos_,
+    code_bpt = new CodeBreakpoint(code, loc->token_pos_,
                                   lowest_pc, lowest_kind);
     RegisterCodeBreakpoint(code_bpt);
   }
-  code_bpt->set_src_bpt(bpt);
-  if (bpt->IsEnabled()) {
+  code_bpt->set_bpt_location(loc);
+  if (loc->AnyEnabled()) {
     code_bpt->Enable();
   }
 }
@@ -1695,7 +1800,7 @@
 }
 
 
-SourceBreakpoint* Debugger::SetBreakpoint(const Script& script,
+BreakpointLocation* Debugger::SetBreakpoint(const Script& script,
                                           intptr_t token_pos,
                                           intptr_t last_token_pos) {
   Function& func = Function::Handle(isolate_);
@@ -1723,14 +1828,14 @@
     intptr_t breakpoint_pos =
         ResolveBreakpointPos(func, token_pos, last_token_pos);
     if (breakpoint_pos >= 0) {
-      SourceBreakpoint* bpt = GetSourceBreakpoint(script, breakpoint_pos);
+      BreakpointLocation* bpt = GetBreakpointLocation(script, breakpoint_pos);
       if (bpt != NULL) {
         // A source breakpoint for this location already exists.
         return bpt;
       }
-      bpt = new SourceBreakpoint(nextId(), script, token_pos, last_token_pos);
+      bpt = new BreakpointLocation(script, token_pos, last_token_pos);
       bpt->SetResolved(func, breakpoint_pos);
-      RegisterSourceBreakpoint(bpt);
+      RegisterBreakpointLocation(bpt);
 
       // Create code breakpoints for all compiled functions we found.
       const intptr_t num_functions = functions.Length();
@@ -1739,7 +1844,6 @@
         ASSERT(func.HasCode());
         MakeCodeBreakpointAt(func, bpt);
       }
-      bpt->Enable();
       if (FLAG_verbose_debug) {
         intptr_t line_number;
         script.GetTokenLocation(breakpoint_pos, &line_number, NULL);
@@ -1748,8 +1852,6 @@
                   func.ToFullyQualifiedCString(),
                   line_number);
       }
-      SignalBpResolved(bpt);
-      SendServiceBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt);
       return bpt;
     }
   }
@@ -1763,24 +1865,24 @@
               func.ToFullyQualifiedCString(),
               line_number);
   }
-  SourceBreakpoint* bpt = GetSourceBreakpoint(script, token_pos);
+  BreakpointLocation* bpt = GetBreakpointLocation(script, token_pos);
   if (bpt == NULL) {
-    bpt = new SourceBreakpoint(nextId(), script, token_pos, last_token_pos);
-    RegisterSourceBreakpoint(bpt);
-    SendServiceBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt);
+    bpt = new BreakpointLocation(script, token_pos, last_token_pos);
+    RegisterBreakpointLocation(bpt);
   }
-  bpt->Enable();
   return bpt;
 }
 
 
 // Synchronize the enabled/disabled state of all code breakpoints
-// associated with the source breakpoint bpt.
-void Debugger::SyncBreakpoint(SourceBreakpoint* bpt) {
+// associated with the breakpoint location loc.
+void Debugger::SyncBreakpointLocation(BreakpointLocation* loc) {
+  bool any_enabled = loc->AnyEnabled();
+
   CodeBreakpoint* cbpt = code_breakpoints_;
   while (cbpt != NULL) {
-    if (bpt == cbpt->src_bpt()) {
-      if (bpt->IsEnabled()) {
+    if (loc == cbpt->bpt_location()) {
+      if (any_enabled) {
         cbpt->Enable();
       } else {
         cbpt->Disable();
@@ -1794,10 +1896,7 @@
 RawError* Debugger::OneTimeBreakAtEntry(const Function& target_function) {
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
-    SourceBreakpoint* bpt = SetBreakpointAtEntry(target_function);
-    if (bpt != NULL) {
-      bpt->SetIsOneShot();
-    }
+    SetBreakpointAtEntry(target_function, true);
     return Error::null();
   } else {
     return isolate_->object_store()->sticky_error();
@@ -1805,21 +1904,51 @@
 }
 
 
-SourceBreakpoint* Debugger::SetBreakpointAtEntry(
-      const Function& target_function) {
+Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function,
+                                           bool single_shot) {
   ASSERT(!target_function.IsNull());
   if (!target_function.is_debuggable()) {
     return NULL;
   }
   const Script& script = Script::Handle(target_function.script());
-  return SetBreakpoint(script,
-                       target_function.token_pos(),
-                       target_function.end_token_pos());
+  BreakpointLocation* bpt_location =
+      SetBreakpoint(script,
+                    target_function.token_pos(),
+                    target_function.end_token_pos());
+  if (single_shot) {
+    return bpt_location->AddSingleShot(this);
+  } else {
+    return bpt_location->AddRepeated(this);
+  }
 }
 
 
-SourceBreakpoint* Debugger::SetBreakpointAtLine(const String& script_url,
-                                                intptr_t line_number) {
+Breakpoint* Debugger::SetBreakpointAtActivation(
+    const Instance& closure) {
+  if (!closure.IsClosure()) {
+    return NULL;
+  }
+  const Function& func = Function::Handle(Closure::function(closure));
+  const Script& script = Script::Handle(func.script());
+  BreakpointLocation* bpt = SetBreakpoint(script,
+                                          func.token_pos(),
+                                          func.end_token_pos());
+  return bpt->AddPerClosure(this, closure);
+}
+
+
+Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url,
+                                          intptr_t line_number) {
+  BreakpointLocation* loc = BreakpointLocationAtLine(script_url, line_number);
+  if (loc != NULL) {
+    return loc->AddRepeated(this);
+  }
+  return NULL;
+}
+
+
+BreakpointLocation* Debugger::BreakpointLocationAtLine(const String& script_url,
+                                                       intptr_t line_number) {
   Library& lib = Library::Handle(isolate_);
   Script& script = Script::Handle(isolate_);
   const GrowableObjectArray& libs =
@@ -1836,7 +1965,8 @@
   if (scripts.Length() == 0) {
     // No script found with given url. Create a latent breakpoint which
     // will be set if the url is loaded later.
-    SourceBreakpoint* latent_bpt = GetLatentBreakpoint(script_url, line_number);
+    BreakpointLocation* latent_bpt = GetLatentBreakpoint(script_url,
+                                                         line_number);
     if (FLAG_verbose_debug) {
       OS::Print("Set latent breakpoint in url '%s' at line %" Pd "\n",
                 script_url.ToCString(),
@@ -1869,7 +1999,7 @@
     return NULL;
   }
 
-  SourceBreakpoint* bpt = NULL;
+  BreakpointLocation* bpt = NULL;
   ASSERT(first_token_idx <= last_token_idx);
   while ((bpt == NULL) && (first_token_idx <= last_token_idx)) {
     bpt = SetBreakpoint(script, first_token_idx, last_token_idx);
@@ -2083,12 +2213,12 @@
 // static
 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   ASSERT(visitor != NULL);
-  SourceBreakpoint* bpt = src_breakpoints_;
+  BreakpointLocation* bpt = breakpoint_locations_;
   while (bpt != NULL) {
     bpt->VisitObjectPointers(visitor);
     bpt = bpt->next();
   }
-  bpt = latent_breakpoints_;
+  bpt = latent_locations_;
   while (bpt != NULL) {
     bpt->VisitObjectPointers(visitor);
     bpt = bpt->next();
@@ -2148,6 +2278,11 @@
       }
     }
   }
+  if (!isolate_->single_step()) {
+    // We are no longer single stepping, make sure that the ThreadInterrupter
+    // is awake.
+    ThreadInterrupter::WakeUp();
+  }
 }
 
 
@@ -2166,13 +2301,13 @@
 
 
 void Debugger::SignalPausedEvent(ActivationFrame* top_frame,
-                                 SourceBreakpoint* bpt) {
+                                 Breakpoint* bpt) {
   resume_action_ = kContinue;
   stepping_fp_ = 0;
   isolate_->set_single_step(false);
   ASSERT(!IsPaused());
   ASSERT(obj_cache_ == NULL);
-  if ((bpt != NULL) && bpt->IsOneShot()) {
+  if ((bpt != NULL) && bpt->IsSingleShot())  {
     RemoveBreakpoint(bpt->id());
     bpt = NULL;
   }
@@ -2254,25 +2389,73 @@
   ASSERT(stack_trace->Length() > 0);
   ActivationFrame* top_frame = stack_trace->FrameAt(0);
   ASSERT(top_frame != NULL);
-  CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc());
-  ASSERT(bpt != NULL);
+  CodeBreakpoint* cbpt = GetCodeBreakpoint(top_frame->pc());
+  ASSERT(cbpt != NULL);
+
+  BreakpointLocation* bpt_location = cbpt->bpt_location_;
+  Breakpoint* bpt_hit = NULL;
+
+  // There may be more than one applicable breakpoint at this location, but we
+  // will report only one as reached. If there is a single-shot breakpoint, we
+  // favor it; then a closure-specific breakpoint ; then an general breakpoint.
+  if (bpt_location != NULL) {
+    Breakpoint* bpt = bpt_location->breakpoints();
+    while (bpt != NULL) {
+      if (bpt->IsSingleShot()) {
+        bpt_hit = bpt;
+        break;
+      }
+      bpt = bpt->next();
+    }
+
+    if (bpt_hit == NULL) {
+      bpt = bpt_location->breakpoints();
+      while (bpt != NULL) {
+        if (bpt->IsPerClosure()) {
+          Object& closure = Object::Handle(top_frame->GetClosure());
+          ASSERT(closure.IsInstance());
+          ASSERT(Instance::Cast(closure).IsClosure());
+          if (closure.raw() == bpt->closure()) {
+            bpt_hit = bpt;
+            break;
+          }
+        }
+        bpt = bpt->next();
+      }
+    }
+
+    if (bpt_hit == NULL) {
+      bpt = bpt_location->breakpoints();
+      while (bpt != NULL) {
+        if (bpt->IsRepeated()) {
+          bpt_hit = bpt;
+          break;
+        }
+        bpt = bpt->next();
+      }
+    }
+  }
+
+  if (bpt_hit == NULL) {
+    return;
+  }
 
   if (FLAG_verbose_debug) {
     OS::Print(">>> hit %s breakpoint at %s:%" Pd " "
               "(token %" Pd ") (address %#" Px ")\n",
-              bpt->IsInternal() ? "internal" : "user",
-              String::Handle(bpt->SourceUrl()).ToCString(),
-              bpt->LineNumber(),
-              bpt->token_pos(),
+              cbpt->IsInternal() ? "internal" : "user",
+              String::Handle(cbpt->SourceUrl()).ToCString(),
+              cbpt->LineNumber(),
+              cbpt->token_pos(),
               top_frame->pc());
   }
 
   ASSERT(stack_trace_ == NULL);
   stack_trace_ = stack_trace;
-  SignalPausedEvent(top_frame, bpt->src_bpt_);
+  SignalPausedEvent(top_frame, bpt_hit);
   HandleSteppingRequest(stack_trace_);
   stack_trace_ = NULL;
-  if (bpt->IsInternal()) {
+  if (cbpt->IsInternal()) {
     RemoveInternalBreakpoints();
   }
 }
@@ -2345,8 +2528,7 @@
   Function& best_fit = Function::Handle(isolate_);
   for (intptr_t i = 0; i < num_closures; i++) {
     closure ^= closures.At(i);
-    if (closure.is_debuggable() &&
-        (function.token_pos() < closure.token_pos()) &&
+    if ((function.token_pos() < closure.token_pos()) &&
         (closure.end_token_pos() < function.end_token_pos()) &&
         (closure.token_pos() <= token_pos) &&
         (token_pos <= closure.end_token_pos()) &&
@@ -2359,7 +2541,7 @@
 
 
 void Debugger::NotifyCompilation(const Function& func) {
-  if (src_breakpoints_ == NULL) {
+  if (breakpoint_locations_ == NULL) {
     // Return with minimal overhead if there are no breakpoints.
     return;
   }
@@ -2372,13 +2554,13 @@
   // Iterate over all source breakpoints to check whether breakpoints
   // need to be set in the newly compiled function.
   Script& script = Script::Handle(isolate_);
-  for (SourceBreakpoint* bpt = src_breakpoints_;
-      bpt != NULL;
-      bpt = bpt->next()) {
-    script = bpt->script();
-    if (FunctionContains(func, script, bpt->token_pos())) {
+  for (BreakpointLocation* loc = breakpoint_locations_;
+      loc != NULL;
+      loc = loc->next()) {
+    script = loc->script();
+    if (FunctionContains(func, script, loc->token_pos())) {
       Function& inner_function = Function::Handle(isolate_);
-      inner_function = FindInnermostClosure(func, bpt->token_pos());
+      inner_function = FindInnermostClosure(func, loc->token_pos());
       if (!inner_function.IsNull()) {
         // The local function of a function we just compiled cannot
         // be compiled already.
@@ -2397,10 +2579,10 @@
       // There is no local function within func that contains the
       // breakpoint token position. Resolve the breakpoint if necessary
       // and set the code breakpoints.
-      if (!bpt->IsResolved()) {
+      if (!loc->IsResolved()) {
         // Resolve source breakpoint in the newly compiled function.
         intptr_t bp_pos =
-            ResolveBreakpointPos(func, bpt->token_pos(), bpt->end_token_pos());
+            ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos());
         if (bp_pos < 0) {
           if (FLAG_verbose_debug) {
             OS::Print("Failed resolving breakpoint for function '%s'\n",
@@ -2408,50 +2590,58 @@
           }
           continue;
         }
-        intptr_t requested_pos = bpt->token_pos();
-        intptr_t requested_end_pos = bpt->end_token_pos();
-        bpt->SetResolved(func, bp_pos);
-        if (FLAG_verbose_debug) {
-          OS::Print("Resolved BP %" Pd " to pos %" Pd ", line %" Pd ", "
-                    "function '%s' (requested range %" Pd "-%" Pd ")\n",
-                    bpt->id(),
-                    bpt->token_pos(),
-                    bpt->LineNumber(),
-                    func.ToFullyQualifiedCString(),
-                    requested_pos,
-                    requested_end_pos);
+        intptr_t requested_pos = loc->token_pos();
+        intptr_t requested_end_pos = loc->end_token_pos();
+        loc->SetResolved(func, bp_pos);
+        Breakpoint* bpt = loc->breakpoints();
+        while (bpt != NULL) {
+          if (FLAG_verbose_debug) {
+            OS::Print("Resolved BP %" Pd " to pos %" Pd ", line %" Pd ", "
+                      "function '%s' (requested range %" Pd "-%" Pd ")\n",
+                      bpt->id(),
+                      loc->token_pos(),
+                      loc->LineNumber(),
+                      func.ToFullyQualifiedCString(),
+                      requested_pos,
+                      requested_end_pos);
+          }
+          SignalBpResolved(bpt);
+          SendServiceBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt);
+          bpt = bpt->next();
         }
-        SignalBpResolved(bpt);
-        SendServiceBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt);
       }
-      ASSERT(bpt->IsResolved());
+      ASSERT(loc->IsResolved());
       if (FLAG_verbose_debug) {
-        OS::Print("Setting breakpoint %" Pd " at line %" Pd " for %s '%s'\n",
-                  bpt->id(),
-                  bpt->LineNumber(),
-                  func.IsClosureFunction() ? "closure" : "function",
-                  String::Handle(func.name()).ToCString());
+        Breakpoint* bpt = loc->breakpoints();
+        while (bpt != NULL) {
+          OS::Print("Setting breakpoint %" Pd " at line %" Pd " for %s '%s'\n",
+                    bpt->id(),
+                    loc->LineNumber(),
+                    func.IsClosureFunction() ? "closure" : "function",
+                    String::Handle(func.name()).ToCString());
+          bpt = bpt->next();
+        }
       }
-      MakeCodeBreakpointAt(func, bpt);
+      MakeCodeBreakpointAt(func, loc);
     }
   }
 }
 
 
 void Debugger::NotifyDoneLoading() {
-  if (latent_breakpoints_ == NULL) {
+  if (latent_locations_ == NULL) {
     // Common, fast path.
     return;
   }
   Library& lib = Library::Handle(isolate_);
   Script& script = Script::Handle(isolate_);
   String& url = String::Handle(isolate_);
-  SourceBreakpoint* bpt = latent_breakpoints_;
-  SourceBreakpoint* prev_bpt = NULL;
+  BreakpointLocation* loc = latent_locations_;
+  BreakpointLocation* prev_loc = NULL;
   const GrowableObjectArray& libs =
       GrowableObjectArray::Handle(isolate_->object_store()->libraries());
-  while (bpt != NULL) {
-    url = bpt->url();
+  while (loc != NULL) {
+    url = loc->url();
     bool found_match = false;
     for (intptr_t i = 0; i < libs.Length(); i++) {
       lib ^= libs.At(i);
@@ -2460,16 +2650,16 @@
         // Found a script with matching url for this latent breakpoint.
         // Unlink the latent breakpoint from the list.
         found_match = true;
-        SourceBreakpoint* matched_bpt = bpt;
-        bpt = bpt->next();
-        if (prev_bpt == NULL) {
-          latent_breakpoints_ = bpt;
+        BreakpointLocation* matched_loc = loc;
+        loc = loc->next();
+        if (prev_loc == NULL) {
+          latent_locations_ = loc;
         } else {
-          prev_bpt->set_next(bpt);
+          prev_loc->set_next(loc);
         }
         // Now find the token range at the requested line and make a
         // new unresolved source breakpoint.
-        intptr_t line_number = matched_bpt->LineNumber();
+        intptr_t line_number = matched_loc->LineNumber();
         ASSERT(line_number >= 0);
         intptr_t first_token_pos, last_token_pos;
         script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos);
@@ -2477,40 +2667,54 @@
             (last_token_pos < 0)) {
           // Script does not contain the given line number or there are no
           // tokens on the line. Drop the breakpoint silently.
-          if (FLAG_verbose_debug) {
-            OS::Print("No code found at line %" Pd ": "
-                      "dropping latent breakpoint %" Pd " in '%s'\n",
-                      line_number,
-                      matched_bpt->id(),
-                      url.ToCString());
+          Breakpoint* bpt = matched_loc->breakpoints();
+          while (bpt != NULL) {
+            if (FLAG_verbose_debug) {
+              OS::Print("No code found at line %" Pd ": "
+                        "dropping latent breakpoint %" Pd " in '%s'\n",
+                        line_number,
+                        bpt->id(),
+                        url.ToCString());
+            }
+            Breakpoint* prev = bpt;
+            bpt = bpt->next();
+            delete prev;
           }
-          delete matched_bpt;
+          delete matched_loc;
         } else {
           // We don't expect to already have a breakpoint for this location.
           // If there is one, assert in debug build but silently drop
           // the latent breakpoint in release build.
-          SourceBreakpoint* existing_bpt =
-              GetSourceBreakpoint(script, first_token_pos);
-          ASSERT(existing_bpt == NULL);
-          if (existing_bpt == NULL) {
+          BreakpointLocation* existing_loc =
+              GetBreakpointLocation(script, first_token_pos);
+          ASSERT(existing_loc == NULL);
+          if (existing_loc == NULL) {
             // Create and register a new source breakpoint for the
             // latent breakpoint.
-            SourceBreakpoint* unresolved_bpt =
-                new SourceBreakpoint(matched_bpt->id(),
-                                     script,
-                                     first_token_pos,
-                                     last_token_pos);
-            RegisterSourceBreakpoint(unresolved_bpt);
-            unresolved_bpt->Enable();
-            if (FLAG_verbose_debug) {
-              OS::Print("Converted latent breakpoint "
-                        "%" Pd " in '%s' at line %" Pd "\n",
-                        matched_bpt->id(),
-                        url.ToCString(),
-                        line_number);
+            BreakpointLocation* unresolved_loc =
+                new BreakpointLocation(script,
+                                       first_token_pos,
+                                       last_token_pos);
+            RegisterBreakpointLocation(unresolved_loc);
+
+            // Move breakpoints over.
+            Breakpoint* bpt = matched_loc->breakpoints();
+            unresolved_loc->set_breakpoints(bpt);
+            matched_loc->set_breakpoints(NULL);
+            while (bpt != NULL) {
+              bpt->set_bpt_location(unresolved_loc);
+              if (FLAG_verbose_debug) {
+                OS::Print("Converted latent breakpoint "
+                          "%" Pd " in '%s' at line %" Pd "\n",
+                          bpt->id(),
+                          url.ToCString(),
+                          line_number);
+              }
+              bpt = bpt->next();
             }
+            SyncBreakpointLocation(unresolved_loc);
           }
-          delete matched_bpt;
+          delete matched_loc;
           // Break out of the iteration over loaded libraries. If the
           // same url has been loaded into more than one library, we
           // only set a breakpoint in the first one.
@@ -2527,12 +2731,16 @@
     if (!found_match) {
       // No matching url found in any of the libraries.
       if (FLAG_verbose_debug) {
-        OS::Print("No match found for latent breakpoint id "
-                  "%" Pd " with url '%s'\n",
-                  bpt->id(),
-                  url.ToCString());
+        Breakpoint* bpt = loc->breakpoints();
+        while (bpt != NULL) {
+          OS::Print("No match found for latent breakpoint id "
+                    "%" Pd " with url '%s'\n",
+                    bpt->id(),
+                    url.ToCString());
+          bpt = bpt->next();
+        }
       }
-      bpt = bpt->next();
+      loc = loc->next();
     }
   }
 }
@@ -2571,32 +2779,51 @@
 // Remove and delete the source breakpoint bpt and its associated
 // code breakpoints.
 void Debugger::RemoveBreakpoint(intptr_t bp_id) {
-  SourceBreakpoint* prev_bpt = NULL;
-  SourceBreakpoint* curr_bpt = src_breakpoints_;
-  while (curr_bpt != NULL) {
-    if (curr_bpt->id() == bp_id) {
-      if (prev_bpt == NULL) {
-        src_breakpoints_ = src_breakpoints_->next();
-      } else {
-        prev_bpt->set_next(curr_bpt->next());
+  BreakpointLocation* prev_loc = NULL;
+  BreakpointLocation* curr_loc = breakpoint_locations_;
+  while (curr_loc != NULL) {
+    Breakpoint* prev_bpt = NULL;
+    Breakpoint* curr_bpt = curr_loc->breakpoints();
+    while (curr_bpt != NULL) {
+      if (curr_bpt->id() == bp_id) {
+        if (prev_bpt == NULL) {
+          curr_loc->set_breakpoints(curr_bpt->next());
+        } else {
+          prev_bpt->set_next(curr_bpt->next());
+        }
+
+        SendServiceBreakpointEvent(ServiceEvent::kBreakpointRemoved, curr_bpt);
+
+        // Remove references from the current debugger pause event.
+        if (pause_event_ != NULL &&
+            pause_event_->type() == DebuggerEvent::kBreakpointReached &&
+            pause_event_->breakpoint() == curr_bpt) {
+          pause_event_->set_breakpoint(NULL);
+        }
+        return;
       }
-      SendServiceBreakpointEvent(ServiceEvent::kBreakpointRemoved, curr_bpt);
+
+      prev_bpt = curr_bpt;
+      curr_bpt = curr_bpt->next();
+    }
+
+    if (curr_loc->breakpoints() == NULL) {
+      if (prev_loc == NULL) {
+        breakpoint_locations_ = curr_loc->next();
+      } else {
+        prev_loc->set_next(curr_loc->next());
+      }
 
       // Remove references from code breakpoints to this source breakpoint,
       // and disable the code breakpoints.
-      UnlinkCodeBreakpoints(curr_bpt);
-      delete curr_bpt;
-
-      // Remove references from the current debugger pause event.
-      if (pause_event_ != NULL &&
-          pause_event_->type() == DebuggerEvent::kBreakpointReached &&
-          pause_event_->breakpoint() == curr_bpt) {
-        pause_event_->set_breakpoint(NULL);
-      }
-      return;
+      UnlinkCodeBreakpoints(curr_loc);
+      BreakpointLocation* next_loc = curr_loc->next();
+      delete curr_loc;
+      curr_loc = next_loc;
+    } else {
+      prev_loc = curr_loc;
+      curr_loc = curr_loc->next();
     }
-    prev_bpt = curr_bpt;
-    curr_bpt = curr_bpt->next();
   }
   // bpt is not a registered breakpoint, nothing to do.
 }
@@ -2607,13 +2834,13 @@
 // returns from the user-defined breakpoint callback. Also, disable the
 // breakpoint so it no longer fires if it should be hit before it gets
 // deleted.
-void Debugger::UnlinkCodeBreakpoints(SourceBreakpoint* src_bpt) {
-  ASSERT(src_bpt != NULL);
+void Debugger::UnlinkCodeBreakpoints(BreakpointLocation* bpt_location) {
+  ASSERT(bpt_location != NULL);
   CodeBreakpoint* curr_bpt = code_breakpoints_;
   while (curr_bpt != NULL) {
-    if (curr_bpt->src_bpt() == src_bpt) {
+    if (curr_bpt->bpt_location() == bpt_location) {
       curr_bpt->Disable();
-      curr_bpt->set_src_bpt(NULL);
+      curr_bpt->set_bpt_location(NULL);
     }
     curr_bpt = curr_bpt->next();
   }
@@ -2626,7 +2853,7 @@
   CodeBreakpoint* prev_bpt = NULL;
   CodeBreakpoint* curr_bpt = code_breakpoints_;
   while (curr_bpt != NULL) {
-    if (curr_bpt->src_bpt() == NULL) {
+    if (curr_bpt->bpt_location() == NULL) {
       if (prev_bpt == NULL) {
         code_breakpoints_ = code_breakpoints_->next();
       } else {
@@ -2644,9 +2871,9 @@
 }
 
 
-SourceBreakpoint* Debugger::GetSourceBreakpoint(const Script& script,
-                                                intptr_t token_pos) {
-  SourceBreakpoint* bpt = src_breakpoints_;
+BreakpointLocation* Debugger::GetBreakpointLocation(const Script& script,
+                                                    intptr_t token_pos) {
+  BreakpointLocation* bpt = breakpoint_locations_;
   while (bpt != NULL) {
     if ((bpt->script_ == script.raw()) && (bpt->token_pos_ == token_pos)) {
       return bpt;
@@ -2657,21 +2884,25 @@
 }
 
 
-SourceBreakpoint* Debugger::GetBreakpointById(intptr_t id) {
-  SourceBreakpoint* bpt = src_breakpoints_;
-  while (bpt != NULL) {
-    if (bpt->id() == id) {
-      return bpt;
+Breakpoint* Debugger::GetBreakpointById(intptr_t id) {
+  BreakpointLocation* loc = breakpoint_locations_;
+  while (loc != NULL) {
+    Breakpoint* bpt = loc->breakpoints();
+    while (bpt != NULL) {
+      if (bpt->id() == id) {
+        return bpt;
+      }
+      bpt = bpt->next();
     }
-    bpt = bpt->next();
+    loc = loc->next();
   }
   return NULL;
 }
 
 
-SourceBreakpoint* Debugger::GetLatentBreakpoint(const String& url,
-                                                intptr_t line) {
-  SourceBreakpoint* bpt = latent_breakpoints_;
+BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url,
+                                                  intptr_t line) {
+  BreakpointLocation* bpt = latent_locations_;
   String& bpt_url = String::Handle(isolate_);
   while (bpt != NULL) {
     bpt_url = bpt->url();
@@ -2681,17 +2912,17 @@
     bpt = bpt->next();
   }
   // No breakpint for this url and line requested. Allocate new one.
-  bpt = new SourceBreakpoint(nextId(), url, line);
-  bpt->set_next(latent_breakpoints_);
-  latent_breakpoints_ = bpt;
+  bpt = new BreakpointLocation(url, line);
+  bpt->set_next(latent_locations_);
+  latent_locations_ = bpt;
   return bpt;
 }
 
 
-void Debugger::RegisterSourceBreakpoint(SourceBreakpoint* bpt) {
+void Debugger::RegisterBreakpointLocation(BreakpointLocation* bpt) {
   ASSERT(bpt->next() == NULL);
-  bpt->set_next(src_breakpoints_);
-  src_breakpoints_ = bpt;
+  bpt->set_next(breakpoint_locations_);
+  breakpoint_locations_ = bpt;
 }
 
 
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index c95deb4..5fb4565 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -18,12 +18,74 @@
 class JSONStream;
 class ObjectPointerVisitor;
 class RemoteObjectCache;
-class SourceBreakpoint;
+class BreakpointLocation;
 class StackFrame;
 
-// SourceBreakpoint represents a user-specified breakpoint location in
-// Dart source. There may be more than one CodeBreakpoint object per
-// SourceBreakpoint.
+// A user-defined breakpoint, which either fires once, for a particular closure,
+// or always. The API's notion of a breakpoint corresponds to this object.
+class Breakpoint {
+ public:
+  Breakpoint(intptr_t id, BreakpointLocation* bpt_location)
+    : id_(id),
+      kind_(Breakpoint::kNone),
+      next_(NULL),
+      closure_(Instance::null()),
+      bpt_location_(bpt_location) {}
+
+  intptr_t id() const { return id_; }
+  Breakpoint* next() const { return next_; }
+  void set_next(Breakpoint* n) { next_ = n; }
+
+  BreakpointLocation* bpt_location() const { return bpt_location_; }
+  void set_bpt_location(BreakpointLocation* new_bpt_location);
+
+  bool IsRepeated() const { return kind_ == kRepeated; }
+  bool IsSingleShot() const { return kind_ == kSingleShot; }
+  bool IsPerClosure() const { return kind_ == kPerClosure; }
+  RawInstance* closure() const { return closure_; }
+
+  void SetIsRepeated() {
+    ASSERT(kind_ == kNone);
+    kind_ = kRepeated;
+  }
+
+  void SetIsSingleShot() {
+    ASSERT(kind_ == kNone);
+    kind_ = kSingleShot;
+  }
+
+  void SetIsPerClosure(const Instance& closure) {
+    ASSERT(kind_ == kNone);
+    kind_ = kPerClosure;
+    closure_ = closure.raw();
+  }
+
+  void PrintJSON(JSONStream* stream);
+
+ private:
+  void VisitObjectPointers(ObjectPointerVisitor* visitor);
+
+  enum ConditionKind {
+    kNone,
+    kRepeated,
+    kSingleShot,
+    kPerClosure,
+  };
+
+  intptr_t id_;
+  ConditionKind kind_;
+  Breakpoint* next_;
+  RawInstance* closure_;
+  BreakpointLocation* bpt_location_;
+
+  friend class BreakpointLocation;
+  DISALLOW_COPY_AND_ASSIGN(Breakpoint);
+};
+
+
+// BreakpointLocation represents a collection of breakpoint conditions at the
+// same token position in Dart source. There may be more than one CodeBreakpoint
+// object per BreakpointLocation.
 // An unresolved breakpoint is one where the underlying code has not
 // been compiled yet. Since the code has not been compiled, we don't know
 // the definitive source location yet. The requested source location may
@@ -32,22 +94,21 @@
 // that is not loaded in the VM when the breakpoint is requested.
 // When a script with matching url is loaded, a latent breakpoint
 // becomes an unresolved breakpoint.
-class SourceBreakpoint {
+class BreakpointLocation {
  public:
   // Create a new unresolved breakpoint.
-  SourceBreakpoint(intptr_t id,
-                   const Script& script,
-                   intptr_t token_pos,
-                   intptr_t end_token_pos);
+  BreakpointLocation(const Script& script,
+                     intptr_t token_pos,
+                     intptr_t end_token_pos);
   // Create a new latent breakpoint.
-  SourceBreakpoint(intptr_t id,
-                   const String& url,
-                   intptr_t line_number);
+  BreakpointLocation(const String& url,
+                     intptr_t line_number);
+
+  ~BreakpointLocation();
 
   RawFunction* function() const { return function_; }
   intptr_t token_pos() const { return token_pos_; }
   intptr_t end_token_pos() const { return end_token_pos_; }
-  intptr_t id() const { return id_; }
 
   RawScript* script() const { return script_; }
   RawString* url() const { return url_; }
@@ -55,45 +116,46 @@
 
   void GetCodeLocation(Library* lib, Script* script, intptr_t* token_pos);
 
-  void Enable();
-  void Disable();
-  bool IsEnabled() const { return is_enabled_; }
+  Breakpoint* AddRepeated(Debugger* dbg);
+  Breakpoint* AddSingleShot(Debugger* dbg);
+  Breakpoint* AddPerClosure(Debugger* dbg, const Instance& closure);
+
+  bool AnyEnabled() const;
   bool IsResolved() const { return is_resolved_; }
   bool IsLatent() const { return token_pos_ < 0; }
 
-  bool IsOneShot() const { return is_one_shot_; }
-  void SetIsOneShot() { is_one_shot_ = true; }
-
-  void PrintJSON(JSONStream* stream);
-
  private:
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
   void SetResolved(const Function& func, intptr_t token_pos);
-  void set_next(SourceBreakpoint* value) { next_ = value; }
-  SourceBreakpoint* next() const { return this->next_; }
 
-  const intptr_t id_;
+  BreakpointLocation* next() const { return this->next_; }
+  void set_next(BreakpointLocation* value) { next_ = value; }
+
+  void AddBreakpoint(Breakpoint* bpt, Debugger* dbg);
+
+  Breakpoint* breakpoints() const { return this->conditions_; }
+  void set_breakpoints(Breakpoint* head) { this->conditions_ = head; }
+
   RawScript* script_;
   RawString* url_;
   intptr_t token_pos_;
   intptr_t end_token_pos_;
   bool is_resolved_;
-  bool is_enabled_;
-  bool is_one_shot_;
-  SourceBreakpoint* next_;
+  BreakpointLocation* next_;
+  Breakpoint* conditions_;
 
   // Valid for resolved breakpoints:
   RawFunction* function_;
   intptr_t line_number_;
 
   friend class Debugger;
-  DISALLOW_COPY_AND_ASSIGN(SourceBreakpoint);
+  DISALLOW_COPY_AND_ASSIGN(BreakpointLocation);
 };
 
 
 // CodeBreakpoint represents a location in compiled code. There may be
-// more than one CodeBreakpoint for one SourceBreakpoint, e.g. when a
+// more than one CodeBreakpoint for one BreakpointLocation, e.g. when a
 // function gets compiled as a regular function and as a closure.
 class CodeBreakpoint {
  public:
@@ -106,7 +168,7 @@
   RawFunction* function() const;
   uword pc() const { return pc_; }
   intptr_t token_pos() const { return token_pos_; }
-  bool IsInternal() const { return src_bpt_ == NULL; }
+  bool IsInternal() const { return bpt_location_ == NULL; }
 
   RawScript* SourceCode();
   RawString* SourceUrl();
@@ -121,8 +183,8 @@
  private:
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
-  SourceBreakpoint* src_bpt() const { return src_bpt_; }
-  void set_src_bpt(SourceBreakpoint* value) { src_bpt_ = value; }
+  BreakpointLocation* bpt_location() const { return bpt_location_; }
+  void set_bpt_location(BreakpointLocation* value) { bpt_location_ = value; }
 
   void set_next(CodeBreakpoint* value) { next_ = value; }
   CodeBreakpoint* next() const { return this->next_; }
@@ -136,7 +198,7 @@
   intptr_t line_number_;
   bool is_enabled_;
 
-  SourceBreakpoint* src_bpt_;
+  BreakpointLocation* bpt_location_;
   CodeBreakpoint* next_;
 
   RawPcDescriptors::Kind breakpoint_kind_;
@@ -194,6 +256,8 @@
                   Object* value);
 
   RawArray* GetLocalVariables();
+  RawObject* GetParameter(intptr_t index);
+  RawObject* GetClosure();
   RawObject* GetReceiver();
 
   const Context& GetSavedCurrentContext();
@@ -273,11 +337,6 @@
 };
 
 
-typedef void BreakpointHandler(Dart_Port isolate_id,
-                               SourceBreakpoint* bpt,
-                               DebuggerStackTrace* stack);
-
-
 class DebuggerEvent {
  public:
   enum EventType {
@@ -315,11 +374,11 @@
     top_frame_ = frame;
   }
 
-  SourceBreakpoint* breakpoint() const {
+  Breakpoint* breakpoint() const {
     ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved);
     return breakpoint_;
   }
-  void set_breakpoint(SourceBreakpoint* bpt) {
+  void set_breakpoint(Breakpoint* bpt) {
     ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved);
     breakpoint_ = bpt;
   }
@@ -341,7 +400,7 @@
   Isolate* isolate_;
   EventType type_;
   ActivationFrame* top_frame_;
-  SourceBreakpoint* breakpoint_;
+  Breakpoint* breakpoint_;
   const Object* exception_;
 };
 
@@ -365,15 +424,21 @@
                                const String& function_name);
 
   // Set breakpoint at closest location to function entry.
-  SourceBreakpoint* SetBreakpointAtEntry(const Function& target_function);
+  Breakpoint* SetBreakpointAtEntry(const Function& target_function,
+                                   bool single_shot);
+  Breakpoint* SetBreakpointAtActivation(const Instance& closure);
 
   // TODO(turnidge): script_url may no longer be specific enough.
-  SourceBreakpoint* SetBreakpointAtLine(const String& script_url,
-                                        intptr_t line_number);
+  Breakpoint* SetBreakpointAtLine(const String& script_url,
+                                  intptr_t line_number);
   RawError* OneTimeBreakAtEntry(const Function& target_function);
 
+  BreakpointLocation* BreakpointLocationAtLine(const String& script_url,
+                                               intptr_t line_number);
+
+
   void RemoveBreakpoint(intptr_t bp_id);
-  SourceBreakpoint* GetBreakpointById(intptr_t id);
+  Breakpoint* GetBreakpointById(intptr_t id);
 
   void SetStepOver();
   void SetSingleStep();
@@ -476,22 +541,22 @@
                                 intptr_t requested_token_pos,
                                 intptr_t last_token_pos);
   void DeoptimizeWorld();
-  SourceBreakpoint* SetBreakpoint(const Script& script,
-                                  intptr_t token_pos,
-                                  intptr_t last_token_pos);
+  BreakpointLocation* SetBreakpoint(const Script& script,
+                                    intptr_t token_pos,
+                                    intptr_t last_token_pos);
   void RemoveInternalBreakpoints();
-  void UnlinkCodeBreakpoints(SourceBreakpoint* src_bpt);
-  SourceBreakpoint* GetLatentBreakpoint(const String& url, intptr_t line);
-  void RegisterSourceBreakpoint(SourceBreakpoint* bpt);
+  void UnlinkCodeBreakpoints(BreakpointLocation* bpt_location);
+  BreakpointLocation* GetLatentBreakpoint(const String& url, intptr_t line);
+  void RegisterBreakpointLocation(BreakpointLocation* bpt);
   void RegisterCodeBreakpoint(CodeBreakpoint* bpt);
-  SourceBreakpoint* GetSourceBreakpoint(const Script& script,
-                                        intptr_t token_pos);
+  BreakpointLocation* GetBreakpointLocation(const Script& script,
+                                            intptr_t token_pos);
   void MakeCodeBreakpointAt(const Function& func,
-                            SourceBreakpoint* bpt);
+                            BreakpointLocation* bpt);
   // Returns NULL if no breakpoint exists for the given address.
   CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address);
 
-  void SyncBreakpoint(SourceBreakpoint* bpt);
+  void SyncBreakpointLocation(BreakpointLocation* loc);
 
   ActivationFrame* TopDartFrame() const;
   static ActivationFrame* CollectDartFrame(Isolate* isolate,
@@ -504,9 +569,9 @@
                                      StackFrame* frame,
                                      const Code& code);
   static DebuggerStackTrace* CollectStackTrace();
-  void SignalBpResolved(SourceBreakpoint *bpt);
+  void SignalBpResolved(Breakpoint *bpt);
   void SignalPausedEvent(ActivationFrame* top_frame,
-                         SourceBreakpoint* bpt);
+                         Breakpoint* bpt);
 
   intptr_t nextId() { return next_id_++; }
 
@@ -531,8 +596,8 @@
   // ID number generator.
   intptr_t next_id_;
 
-  SourceBreakpoint* latent_breakpoints_;
-  SourceBreakpoint* src_breakpoints_;
+  BreakpointLocation* latent_locations_;
+  BreakpointLocation* breakpoint_locations_;
   CodeBreakpoint* code_breakpoints_;
 
   // Tells debugger what to do when resuming execution after a breakpoint.
@@ -565,7 +630,7 @@
   static EventHandler* event_handler_;
 
   friend class Isolate;
-  friend class SourceBreakpoint;
+  friend class BreakpointLocation;
   DISALLOW_COPY_AND_ASSIGN(Debugger);
 };
 
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 5b1c868..fc6a5ea 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -130,13 +130,13 @@
     }
   } else if (event->type() == DebuggerEvent::kBreakpointResolved) {
     if (bp_resolved_handler != NULL) {
-      SourceBreakpoint* bpt = event->breakpoint();
+      Breakpoint* bpt = event->breakpoint();
       ASSERT(bpt != NULL);
       Dart_CodeLocation location;
       Library& library = Library::Handle(isolate);
       Script& script = Script::Handle(isolate);
       intptr_t token_pos;
-      bpt->GetCodeLocation(&library, &script, &token_pos);
+      bpt->bpt_location()->GetCodeLocation(&library, &script, &token_pos);
       location.script_url = Api::NewHandle(isolate, script.url());
       location.library_id = library.index();
       location.token_pos = token_pos;
@@ -341,7 +341,7 @@
 
   Debugger* debugger = isolate->debugger();
   ASSERT(debugger != NULL);
-  SourceBreakpoint* bpt =
+  Breakpoint* bpt =
       debugger->SetBreakpointAtLine(script_url, line_number);
   if (bpt == NULL) {
     return Api::NewError("%s: could not set breakpoint at line %" Pd " in '%s'",
@@ -357,12 +357,12 @@
   Debugger* debugger = isolate->debugger();
   ASSERT(debugger != NULL);
 
-  SourceBreakpoint* bpt = debugger->GetBreakpointById(bp_id);
+  Breakpoint* bpt = debugger->GetBreakpointById(bp_id);
   if (bpt == NULL) {
     return Api::NewError("%s: breakpoint with id %" Pd " does not exist",
                            CURRENT_FUNC, bp_id);
   }
-  return Api::NewHandle(isolate, bpt->url());
+  return Api::NewHandle(isolate, bpt->bpt_location()->url());
 }
 
 
@@ -372,12 +372,12 @@
   Debugger* debugger = isolate->debugger();
   ASSERT(debugger != NULL);
 
-  SourceBreakpoint* bpt = debugger->GetBreakpointById(bp_id);
+  Breakpoint* bpt = debugger->GetBreakpointById(bp_id);
   if (bpt == NULL) {
     return Api::NewError("%s: breakpoint with id %" Pd " does not exist",
                          CURRENT_FUNC, bp_id);
   }
-  return Dart_NewInteger(bpt->LineNumber());
+  return Dart_NewInteger(bpt->bpt_location()->LineNumber());
 }
 
 
@@ -411,7 +411,7 @@
                          function_name.ToCString());
   }
 
-  SourceBreakpoint* bpt = debugger->SetBreakpointAtEntry(bp_target);
+  Breakpoint* bpt = debugger->SetBreakpointAtEntry(bp_target, false);
   if (bpt == NULL) {
     const char* target_name = Debugger::QualifiedFunctionName(bp_target);
     return Api::NewError("%s: no breakpoint location found in '%s'",
diff --git a/runtime/vm/debugger_arm.cc b/runtime/vm/debugger_arm.cc
index fc924ca..608d6d2 100644
--- a/runtime/vm/debugger_arm.cc
+++ b/runtime/vm/debugger_arm.cc
@@ -20,35 +20,25 @@
 
 void CodeBreakpoint::PatchCode() {
   ASSERT(!is_enabled_);
-  const Code& code = Code::Handle(code_);
-  const Instructions& instrs = Instructions::Handle(code.instructions());
-  Isolate* isolate = Isolate::Current();
-  {
-    WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
-    switch (breakpoint_kind_) {
-      case RawPcDescriptors::kIcCall:
-      case RawPcDescriptors::kUnoptStaticCall: {
-        saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
-        CodePatcher::PatchStaticCallAt(
-            pc_, code, isolate->stub_code()->ICCallBreakpointEntryPoint());
-        break;
-      }
-      case RawPcDescriptors::kClosureCall: {
-        saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
-        CodePatcher::PatchStaticCallAt(
-            pc_, code, isolate->stub_code()->ClosureCallBreakpointEntryPoint());
-        break;
-      }
-      case RawPcDescriptors::kRuntimeCall: {
-        saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
-        CodePatcher::PatchStaticCallAt(
-            pc_, code, isolate->stub_code()->RuntimeCallBreakpointEntryPoint());
-        break;
-      }
-      default:
-        UNREACHABLE();
-    }
+  StubCode* stub_code = Isolate::Current()->stub_code();
+  uword stub_target = 0;
+  switch (breakpoint_kind_) {
+    case RawPcDescriptors::kIcCall:
+    case RawPcDescriptors::kUnoptStaticCall:
+      stub_target = stub_code->ICCallBreakpointEntryPoint();
+      break;
+    case RawPcDescriptors::kClosureCall:
+      stub_target = stub_code->ClosureCallBreakpointEntryPoint();
+      break;
+    case RawPcDescriptors::kRuntimeCall:
+      stub_target = stub_code->RuntimeCallBreakpointEntryPoint();
+      break;
+    default:
+      UNREACHABLE();
   }
+  const Code& code = Code::Handle(code_);
+  saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
+  CodePatcher::PatchStaticCallAt(pc_, code, stub_target);
   is_enabled_ = true;
 }
 
@@ -56,20 +46,16 @@
 void CodeBreakpoint::RestoreCode() {
   ASSERT(is_enabled_);
   const Code& code = Code::Handle(code_);
-  const Instructions& instrs = Instructions::Handle(code.instructions());
-  {
-    WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
-    switch (breakpoint_kind_) {
-      case RawPcDescriptors::kIcCall:
-      case RawPcDescriptors::kUnoptStaticCall:
-      case RawPcDescriptors::kClosureCall:
-      case RawPcDescriptors::kRuntimeCall: {
-        CodePatcher::PatchStaticCallAt(pc_, code, saved_value_);
-        break;
-      }
-      default:
-        UNREACHABLE();
+  switch (breakpoint_kind_) {
+    case RawPcDescriptors::kIcCall:
+    case RawPcDescriptors::kUnoptStaticCall:
+    case RawPcDescriptors::kClosureCall:
+    case RawPcDescriptors::kRuntimeCall: {
+      CodePatcher::PatchStaticCallAt(pc_, code, saved_value_);
+      break;
     }
+    default:
+      UNREACHABLE();
   }
   is_enabled_ = false;
 }
diff --git a/runtime/vm/debugger_mips.cc b/runtime/vm/debugger_mips.cc
index e3918e67..96d4632 100644
--- a/runtime/vm/debugger_mips.cc
+++ b/runtime/vm/debugger_mips.cc
@@ -20,35 +20,25 @@
 
 void CodeBreakpoint::PatchCode() {
   ASSERT(!is_enabled_);
-  const Code& code = Code::Handle(code_);
-  const Instructions& instrs = Instructions::Handle(code.instructions());
-  Isolate* isolate = Isolate::Current();
-  {
-    WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
-    switch (breakpoint_kind_) {
-      case RawPcDescriptors::kIcCall:
-      case RawPcDescriptors::kUnoptStaticCall: {
-        saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
-        CodePatcher::PatchStaticCallAt(
-            pc_, code, isolate->stub_code()->ICCallBreakpointEntryPoint());
-        break;
-      }
-      case RawPcDescriptors::kClosureCall: {
-        saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
-        CodePatcher::PatchStaticCallAt(
-            pc_, code, isolate->stub_code()->ClosureCallBreakpointEntryPoint());
-        break;
-      }
-      case RawPcDescriptors::kRuntimeCall: {
-        saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
-        CodePatcher::PatchStaticCallAt(
-            pc_, code, isolate->stub_code()->RuntimeCallBreakpointEntryPoint());
-        break;
-      }
-      default:
-        UNREACHABLE();
-    }
+  StubCode* stub_code = Isolate::Current()->stub_code();
+  uword stub_target = 0;
+  switch (breakpoint_kind_) {
+    case RawPcDescriptors::kIcCall:
+    case RawPcDescriptors::kUnoptStaticCall:
+      stub_target = stub_code->ICCallBreakpointEntryPoint();
+      break;
+    case RawPcDescriptors::kClosureCall:
+      stub_target = stub_code->ClosureCallBreakpointEntryPoint();
+      break;
+    case RawPcDescriptors::kRuntimeCall:
+      stub_target = stub_code->RuntimeCallBreakpointEntryPoint();
+      break;
+    default:
+      UNREACHABLE();
   }
+  const Code& code = Code::Handle(code_);
+  saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
+  CodePatcher::PatchStaticCallAt(pc_, code, stub_target);
   is_enabled_ = true;
 }
 
@@ -56,20 +46,16 @@
 void CodeBreakpoint::RestoreCode() {
   ASSERT(is_enabled_);
   const Code& code = Code::Handle(code_);
-  const Instructions& instrs = Instructions::Handle(code.instructions());
-  {
-    WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
-    switch (breakpoint_kind_) {
-      case RawPcDescriptors::kIcCall:
-      case RawPcDescriptors::kUnoptStaticCall:
-      case RawPcDescriptors::kClosureCall:
-      case RawPcDescriptors::kRuntimeCall: {
-        CodePatcher::PatchStaticCallAt(pc_, code, saved_value_);
-        break;
-      }
-      default:
-        UNREACHABLE();
+  switch (breakpoint_kind_) {
+    case RawPcDescriptors::kIcCall:
+    case RawPcDescriptors::kUnoptStaticCall:
+    case RawPcDescriptors::kClosureCall:
+    case RawPcDescriptors::kRuntimeCall: {
+      CodePatcher::PatchStaticCallAt(pc_, code, saved_value_);
+      break;
     }
+    default:
+      UNREACHABLE();
   }
   is_enabled_ = false;
 }
diff --git a/runtime/vm/debugger_test.cc b/runtime/vm/debugger_test.cc
index 5545700..72eff9e 100644
--- a/runtime/vm/debugger_test.cc
+++ b/runtime/vm/debugger_test.cc
@@ -69,20 +69,20 @@
     }
     ExpectSubstringF(
         js.ToCString(),
-        "[{\"type\":\"Breakpoint\",\"id\":\"breakpoints\\/2\","
+        "[{\"type\":\"Breakpoint\",\"fixedId\":true,\"id\":\"breakpoints\\/2\","
         "\"breakpointNumber\":2,\"resolved\":false,"
         "\"location\":{\"type\":\"Location\","
-        "\"script\":{\"type\":\"@Script\","
+        "\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
         "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\","
-        "\"name\":\"test-lib\","
-        "\"kind\":\"script\"},\"tokenPos\":14}},"
-        "{\"type\":\"Breakpoint\",\"id\":\"breakpoints\\/1\","
+        "\"uri\":\"test-lib\","
+        "\"_kind\":\"script\"},\"tokenPos\":14}},"
+        "{\"type\":\"Breakpoint\",\"fixedId\":true,\"id\":\"breakpoints\\/1\","
         "\"breakpointNumber\":1,\"resolved\":false,"
         "\"location\":{\"type\":\"Location\","
-        "\"script\":{\"type\":\"@Script\","
+        "\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
         "\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\","
-        "\"name\":\"test-lib\","
-        "\"kind\":\"script\"},\"tokenPos\":5}}]",
+        "\"uri\":\"test-lib\","
+        "\"_kind\":\"script\"},\"tokenPos\":5}}]",
         vmlib.index(), vmlib.index());
   }
 }
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 1ef229f..75ef322 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -194,7 +194,7 @@
 }
 
 
-static void JumpToExceptionHandler(Isolate* isolate,
+static void JumpToExceptionHandler(Thread* thread,
                                    uword program_counter,
                                    uword stack_pointer,
                                    uword frame_pointer,
@@ -216,17 +216,17 @@
   // object (may be raw null) in the kStackTraceObjectReg register.
 
   Simulator::Current()->Longjmp(program_counter, stack_pointer, frame_pointer,
-                                raw_exception, raw_stacktrace, isolate);
+                                raw_exception, raw_stacktrace, thread);
 #else
   // Prepare for unwinding frames by destroying all the stack resources
   // in the previous frames.
-  StackResource::Unwind(isolate);
+  StackResource::Unwind(thread->isolate());
 
   // Call a stub to set up the exception object in kExceptionObjectReg,
   // to set up the stacktrace object in kStackTraceObjectReg, and to
   // continue execution at the given pc in the given frame.
   typedef void (*ExcpHandler)(uword, uword, uword, RawObject*, RawObject*,
-                              Isolate*);
+                              Thread*);
   ExcpHandler func = reinterpret_cast<ExcpHandler>(
       StubCode::JumpToExceptionHandlerEntryPoint());
 
@@ -236,7 +236,7 @@
                 stack_pointer - current_sp);
 
   func(program_counter, stack_pointer, frame_pointer,
-       raw_exception, raw_stacktrace, isolate);
+       raw_exception, raw_stacktrace, thread);
 #endif
   UNREACHABLE();
 }
@@ -288,10 +288,11 @@
 }
 
 
-static void ThrowExceptionHelper(Isolate* isolate,
+static void ThrowExceptionHelper(Thread* thread,
                                  const Instance& incoming_exception,
                                  const Instance& existing_stacktrace,
                                  const bool is_rethrow) {
+  Isolate* isolate = thread->isolate();
   bool use_preallocated_stacktrace = false;
   Instance& exception = Instance::Handle(isolate, incoming_exception.raw());
   if (exception.IsNull()) {
@@ -363,7 +364,7 @@
   }
   if (handler_exists) {
     // Found a dart handler for the exception, jump to it.
-    JumpToExceptionHandler(isolate,
+    JumpToExceptionHandler(thread,
                            handler_pc,
                            handler_sp,
                            handler_fp,
@@ -380,7 +381,7 @@
     const UnhandledException& unhandled_exception = UnhandledException::Handle(
         isolate, UnhandledException::New(exception, stacktrace));
     stacktrace = Stacktrace::null();
-    JumpToExceptionHandler(isolate,
+    JumpToExceptionHandler(thread,
                            handler_pc,
                            handler_sp,
                            handler_fp,
@@ -474,29 +475,30 @@
 }
 
 
-void Exceptions::Throw(Isolate* isolate, const Instance& exception) {
+void Exceptions::Throw(Thread* thread, const Instance& exception) {
   // Do not notify debugger on stack overflow and out of memory exceptions.
   // The VM would crash when the debugger calls back into the VM to
   // get values of variables.
+  Isolate* isolate = thread->isolate();
   if (exception.raw() != isolate->object_store()->out_of_memory() &&
       exception.raw() != isolate->object_store()->stack_overflow()) {
     isolate->debugger()->SignalExceptionThrown(exception);
   }
   // Null object is a valid exception object.
-  ThrowExceptionHelper(isolate, exception, Stacktrace::Handle(isolate), false);
+  ThrowExceptionHelper(thread, exception, Stacktrace::Handle(isolate), false);
 }
 
-
-void Exceptions::ReThrow(Isolate* isolate,
+void Exceptions::ReThrow(Thread* thread,
                          const Instance& exception,
                          const Instance& stacktrace) {
   // Null object is a valid exception object.
-  ThrowExceptionHelper(isolate, exception, stacktrace, true);
+  ThrowExceptionHelper(thread, exception, stacktrace, true);
 }
 
 
 void Exceptions::PropagateError(const Error& error) {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate->top_exit_frame_info() != 0);
   if (error.IsUnhandledException()) {
     // If the error object represents an unhandled exception, then
@@ -504,7 +506,7 @@
     const UnhandledException& uhe = UnhandledException::Cast(error);
     const Instance& exc = Instance::Handle(isolate, uhe.exception());
     const Instance& stk = Instance::Handle(isolate, uhe.stacktrace());
-    Exceptions::ReThrow(isolate, exc, stk);
+    Exceptions::ReThrow(thread, exc, stk);
   } else {
     // Return to the invocation stub and return this error object.  The
     // C++ code which invoked this dart sequence can check and do the
@@ -513,7 +515,7 @@
     uword handler_sp = 0;
     uword handler_fp = 0;
     FindErrorHandler(&handler_pc, &handler_sp, &handler_fp);
-    JumpToExceptionHandler(isolate, handler_pc, handler_sp, handler_fp, error,
+    JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error,
                            Stacktrace::Handle(isolate));  // Null stacktrace.
   }
   UNREACHABLE();
@@ -521,7 +523,8 @@
 
 
 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   const Object& result = Object::Handle(isolate, Create(type, arguments));
   if (result.IsError()) {
     // We got an error while constructing the exception object.
@@ -529,24 +532,26 @@
     PropagateError(Error::Cast(result));
   } else {
     ASSERT(result.IsInstance());
-    Throw(isolate, Instance::Cast(result));
+    Throw(thread, Instance::Cast(result));
   }
 }
 
 
 void Exceptions::ThrowOOM() {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   const Instance& oom = Instance::Handle(
       isolate, isolate->object_store()->out_of_memory());
-  Throw(isolate, oom);
+  Throw(thread, oom);
 }
 
 
 void Exceptions::ThrowStackOverflow() {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   const Instance& stack_overflow = Instance::Handle(
       isolate, isolate->object_store()->stack_overflow());
-  Throw(isolate, stack_overflow);
+  Throw(thread, stack_overflow);
 }
 
 
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index de7e9e3..0264778 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -26,13 +26,14 @@
 class StackFrame;
 class Stacktrace;
 class String;
+class Thread;
 
 class Exceptions : AllStatic {
  public:
   static const char* kCastErrorDstName;
 
-  static void Throw(Isolate* isolate, const Instance& exception);
-  static void ReThrow(Isolate* isolate,
+  static void Throw(Thread* thread, const Instance& exception);
+  static void ReThrow(Thread* thread,
                       const Instance& exception,
                       const Instance& stacktrace);
   static void PropagateError(const Error& error);
@@ -70,6 +71,8 @@
   };
 
   static void ThrowByType(ExceptionType type, const Array& arguments);
+  // Uses the preallocated out of memory exception to avoid calling
+  // into Dart code or allocating any code.
   static void ThrowOOM();
   static void ThrowStackOverflow();
   static void ThrowArgumentError(const Instance& arg);
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 78f850e..07e3086 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -118,6 +118,7 @@
   }
   blocked_cpu_registers_[SPREG] = true;
   blocked_cpu_registers_[FPREG] = true;
+  blocked_cpu_registers_[THR] = true;
 
   // FpuTMP is used as scratch by optimized code and parallel move resolver.
   blocked_fpu_registers_[FpuTMP] = true;
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 5a72f78..c414fe9 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -1876,13 +1876,14 @@
     PushArgumentInstr* push_right = PushArgument(for_right_value.value());
     arguments->Add(push_right);
 
+    const intptr_t kNumArgsChecked = 2;
     Definition* result = new(Z) InstanceCallInstr(
         node->token_pos(),
         Symbols::EqualOperator(),
         Token::kEQ,  // Result is negated later for kNE.
         arguments,
         Object::null_array(),
-        2,
+        kNumArgsChecked,
         owner()->ic_data_array());
     if (node->kind() == Token::kNE) {
       if (Isolate::Current()->TypeChecksEnabled() ||
@@ -3093,12 +3094,13 @@
   BuildInstanceSetterArguments(node, arguments, kResultNotNeeded);
   const String& name =
       String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
+  const intptr_t kNumArgsChecked = 1;  // Do not check value type.
   InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(),
                                                      name,
                                                      Token::kSET,
                                                      arguments,
                                                      Object::null_array(),
-                                                     2,  // Checked arg count.
+                                                     kNumArgsChecked,
                                                      owner()->ic_data_array());
   ReturnDefinition(call);
 }
@@ -3110,12 +3112,13 @@
   BuildInstanceSetterArguments(node, arguments, kResultNeeded);
   const String& name =
       String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
+  const intptr_t kNumArgsChecked = 1;  // Do not check value type.
   Do(new(Z) InstanceCallInstr(node->token_pos(),
                               name,
                               Token::kSET,
                               arguments,
                               Object::null_array(),
-                              2,  // Checked argument count.
+                              kNumArgsChecked,
                               owner()->ic_data_array()));
   ReturnDefinition(BuildLoadExprTemp());
 }
@@ -3738,7 +3741,7 @@
     }
   } else {
     // Generate dynamic call to operator []=.
-    const intptr_t checked_argument_count = 3;
+    const intptr_t checked_argument_count = 2;  // Do not check for value type.
     const String& name =
         String::ZoneHandle(Z, Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
     InstanceCallInstr* store =
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index e6f8b25..b2daac8 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -32,20 +32,20 @@
 // (factory-name-symbol, result-cid, fingerprint).
 #define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
   V(_ListFactory, kArrayCid, 335347617)                                        \
-  V(_GrowableListWithData, kGrowableObjectArrayCid, 536409567)                 \
+  V(_GrowableListWithData, kGrowableObjectArrayCid, 2094352700)                \
   V(_GrowableListFactory, kGrowableObjectArrayCid, 619206641)                  \
-  V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 1234236264)                     \
-  V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 89436950)                     \
-  V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 2114336727)     \
-  V(_Int16ArrayFactory, kTypedDataInt16ArrayCid, 779429598)                    \
-  V(_Uint16ArrayFactory, kTypedDataUint16ArrayCid, 351653952)                  \
-  V(_Int32ArrayFactory, kTypedDataInt32ArrayCid, 1909366715)                   \
-  V(_Uint32ArrayFactory, kTypedDataUint32ArrayCid, 32690110)                   \
-  V(_Int64ArrayFactory, kTypedDataInt64ArrayCid, 1987760123)                   \
-  V(_Uint64ArrayFactory, kTypedDataUint64ArrayCid, 1205087814)                 \
-  V(_Float64ArrayFactory, kTypedDataFloat64ArrayCid, 77468920)                 \
-  V(_Float32ArrayFactory, kTypedDataFloat32ArrayCid, 1988570712)               \
-  V(_Float32x4ArrayFactory, kTypedDataFloat32x4ArrayCid, 953075137)            \
+  V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 439914696)                      \
+  V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1442599030)                   \
+  V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 1320015159)     \
+  V(_Int16ArrayFactory, kTypedDataInt16ArrayCid, 2132591678)                   \
+  V(_Uint16ArrayFactory, kTypedDataUint16ArrayCid, 1704816032)                 \
+  V(_Int32ArrayFactory, kTypedDataInt32ArrayCid, 1115045147)                   \
+  V(_Uint32ArrayFactory, kTypedDataUint32ArrayCid, 1385852190)                 \
+  V(_Int64ArrayFactory, kTypedDataInt64ArrayCid, 1193438555)                   \
+  V(_Uint64ArrayFactory, kTypedDataUint64ArrayCid, 410766246)                  \
+  V(_Float64ArrayFactory, kTypedDataFloat64ArrayCid, 1430631000)               \
+  V(_Float32ArrayFactory, kTypedDataFloat32ArrayCid, 1194249144)               \
+  V(_Float32x4ArrayFactory, kTypedDataFloat32x4ArrayCid, 158753569)            \
 
 
 // Class that recognizes factories and returns corresponding result cid.
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index ae31c41..865e027 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -1037,10 +1037,6 @@
       case 2:
         label_address = stub_code->TwoArgsOptimizedCheckInlineCacheEntryPoint();
         break;
-      case 3:
-        label_address =
-            stub_code->ThreeArgsOptimizedCheckInlineCacheEntryPoint();
-        break;
       default:
         UNIMPLEMENTED();
     }
@@ -1068,9 +1064,6 @@
     case 2:
       label_address = stub_code->TwoArgsCheckInlineCacheEntryPoint();
       break;
-    case 3:
-      label_address = stub_code->ThreeArgsCheckInlineCacheEntryPoint();
-      break;
     default:
       UNIMPLEMENTED();
   }
@@ -1190,6 +1183,21 @@
 }
 
 
+static uword RegMaskBit(Register reg) {
+  return ((reg) != kNoRegister) ? (1 << (reg)) : 0;
+}
+
+
+// Mask of globally reserved registers. Some other registers are only reserved
+// in particular code (e.g., ARGS_DESC_REG in intrinsics).
+static const uword kReservedCpuRegisters = RegMaskBit(SPREG)
+                                         | RegMaskBit(FPREG)
+                                         | RegMaskBit(TMP)
+                                         | RegMaskBit(TMP2)
+                                         | RegMaskBit(PP)
+                                         | RegMaskBit(THR);
+
+
 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) {
   ASSERT(!is_optimizing());
 
@@ -1204,6 +1212,13 @@
     blocked_registers[i] = false;
   }
 
+  // Block all registers globally reserved by the assembler, etc.
+  for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
+    if ((kReservedCpuRegisters & (1 << i)) != 0) {
+      blocked_registers[i] = true;
+    }
+  }
+
   // Mark all fixed input, temp and output registers as used.
   for (intptr_t i = 0; i < locs->input_count(); i++) {
     Location loc = locs->in(i);
@@ -1229,19 +1244,6 @@
     blocked_registers[locs->out(0).reg()] = true;
   }
 
-  // Do not allocate known registers.
-  blocked_registers[SPREG] = true;
-  blocked_registers[FPREG] = true;
-  if (TMP != kNoRegister) {
-    blocked_registers[TMP] = true;
-  }
-  if (TMP2 != kNoRegister) {
-    blocked_registers[TMP2] = true;
-  }
-  if (PP != kNoRegister) {
-    blocked_registers[PP] = true;
-  }
-
   // Block all non-free registers.
   for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) {
     blocked_registers[i] = true;
@@ -1495,25 +1497,15 @@
 }
 
 
-static inline intptr_t MaskBit(Register reg) {
-  return (reg != kNoRegister) ? (1 << reg) : 0;
-}
-
-
 ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope(
     ParallelMoveResolver* resolver, Register blocked)
     : resolver_(resolver),
       reg_(kNoRegister),
       spilled_(false) {
-  uword blocked_mask = MaskBit(blocked)
-                     | MaskBit(SPREG)
-                     | MaskBit(FPREG)
-                     | MaskBit(TMP)
-                     | MaskBit(TMP2)
-                     | MaskBit(PP);
+  uword blocked_mask = RegMaskBit(blocked) | kReservedCpuRegisters;
   if (resolver->compiler_->intrinsic_mode()) {
     // Block additional registers that must be preserved for intrinsics.
-    blocked_mask |= MaskBit(ARGS_DESC_REG);
+    blocked_mask |= RegMaskBit(ARGS_DESC_REG);
   }
   reg_ = static_cast<Register>(
       resolver_->AllocateScratchRegister(Location::kRegister,
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 741bd96..3fd9733 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -764,13 +764,13 @@
   const int min_num_pos_args = num_fixed_params;
   const int max_num_pos_args = num_fixed_params + num_opt_pos_params;
 
-  __ ldr(R8, FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
+  __ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
   // Check that min_num_pos_args <= num_pos_args.
   Label wrong_num_arguments;
-  __ CompareImmediate(R8, Smi::RawValue(min_num_pos_args));
+  __ CompareImmediate(R9, Smi::RawValue(min_num_pos_args));
   __ b(&wrong_num_arguments, LT);
   // Check that num_pos_args <= max_num_pos_args.
-  __ CompareImmediate(R8, Smi::RawValue(max_num_pos_args));
+  __ CompareImmediate(R9, Smi::RawValue(max_num_pos_args));
   __ b(&wrong_num_arguments, GT);
 
   // Copy positional arguments.
@@ -778,30 +778,30 @@
   // to fp[kFirstLocalSlotFromFp - i].
 
   __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  // Since R7 and R8 are Smi, use LSL 1 instead of LSL 2.
+  // Since R7 and R9 are Smi, use LSL 1 instead of LSL 2.
   // Let R7 point to the last passed positional argument, i.e. to
   // fp[kParamEndSlotFromFp + num_args - (num_pos_args - 1)].
-  __ sub(R7, R7, Operand(R8));
+  __ sub(R7, R7, Operand(R9));
   __ add(R7, FP, Operand(R7, LSL, 1));
   __ add(R7, R7, Operand((kParamEndSlotFromFp + 1) * kWordSize));
 
   // Let R6 point to the last copied positional argument, i.e. to
   // fp[kFirstLocalSlotFromFp - (num_pos_args - 1)].
   __ AddImmediate(R6, FP, (kFirstLocalSlotFromFp + 1) * kWordSize);
-  __ sub(R6, R6, Operand(R8, LSL, 1));  // R8 is a Smi.
-  __ SmiUntag(R8);
+  __ sub(R6, R6, Operand(R9, LSL, 1));  // R9 is a Smi.
+  __ SmiUntag(R9);
   Label loop, loop_condition;
   __ b(&loop_condition);
   // We do not use the final allocation index of the variable here, i.e.
   // scope->VariableAt(i)->index(), because captured variables still need
   // to be copied to the context that is not yet allocated.
-  const Address argument_addr(R7, R8, LSL, 2);
-  const Address copy_addr(R6, R8, LSL, 2);
+  const Address argument_addr(R7, R9, LSL, 2);
+  const Address copy_addr(R6, R9, LSL, 2);
   __ Bind(&loop);
   __ ldr(IP, argument_addr);
   __ str(IP, copy_addr);
   __ Bind(&loop_condition);
-  __ subs(R8, R8, Operand(1));
+  __ subs(R9, R9, Operand(1));
   __ b(&loop, PL);
 
   // Copy or initialize optional named arguments.
@@ -832,9 +832,9 @@
     }
     // Generate code handling each optional parameter in alphabetical order.
     __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-    __ ldr(R8,
+    __ ldr(R9,
            FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
-    __ SmiUntag(R8);
+    __ SmiUntag(R9);
     // Let R7 point to the first passed argument, i.e. to
     // fp[kParamEndSlotFromFp + num_args - 0]; num_args (R7) is Smi.
     __ add(R7, FP, Operand(R7, LSL, 1));
@@ -887,16 +887,16 @@
     }
   } else {
     ASSERT(num_opt_pos_params > 0);
-    __ ldr(R8,
+    __ ldr(R9,
            FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
-    __ SmiUntag(R8);
+    __ SmiUntag(R9);
     for (int i = 0; i < num_opt_pos_params; i++) {
       Label next_parameter;
       // Handle this optional positional parameter only if k or fewer positional
       // arguments have been passed, where k is param_pos, the position of this
       // optional parameter in the formal parameter list.
       const int param_pos = num_fixed_params + i;
-      __ CompareImmediate(R8, param_pos);
+      __ CompareImmediate(R9, param_pos);
       __ b(&next_parameter, GT);
       // Load R5 with default argument.
       const Object& value = Object::ZoneHandle(
@@ -914,8 +914,8 @@
     if (check_correct_named_args) {
       __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
       __ SmiUntag(R7);
-      // Check that R8 equals R7, i.e. no named arguments passed.
-      __ cmp(R8, Operand(R7));
+      // Check that R9 equals R7, i.e. no named arguments passed.
+      __ cmp(R9, Operand(R7));
       __ b(&all_arguments_processed, EQ);
     }
   }
@@ -937,17 +937,17 @@
   // an issue anymore.
 
   // R4 : arguments descriptor array.
-  __ ldr(R8, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(R8);
+  __ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
+  __ SmiUntag(R9);
   __ add(R7, FP, Operand((kParamEndSlotFromFp + 1) * kWordSize));
-  const Address original_argument_addr(R7, R8, LSL, 2);
+  const Address original_argument_addr(R7, R9, LSL, 2);
   __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
   Label null_args_loop, null_args_loop_condition;
   __ b(&null_args_loop_condition);
   __ Bind(&null_args_loop);
   __ str(IP, original_argument_addr);
   __ Bind(&null_args_loop_condition);
-  __ subs(R8, R8, Operand(1));
+  __ subs(R9, R9, Operand(1));
   __ b(&null_args_loop, PL);
 }
 
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index ee53c720..e4a5183 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -1403,9 +1403,6 @@
     // Recognized []= operators.
     case MethodRecognizer::kObjectArraySetIndexed:
     case MethodRecognizer::kGrowableArraySetIndexed:
-      if (ArgIsAlways(kSmiCid, ic_data, 2)) {
-        value_check = ic_data.AsUnaryClassChecksForArgNr(2);
-      }
       return InlineSetIndexed(kind, target, call, receiver, token_pos,
                               value_check, entry, last);
     case MethodRecognizer::kInt8ArraySetIndexed:
@@ -1415,22 +1412,19 @@
     case MethodRecognizer::kExternalUint8ClampedArraySetIndexed:
     case MethodRecognizer::kInt16ArraySetIndexed:
     case MethodRecognizer::kUint16ArraySetIndexed:
-      if (!ArgIsAlways(kSmiCid, ic_data, 2)) {
-        return false;
-      }
-      value_check = ic_data.AsUnaryClassChecksForArgNr(2);
+      // Optimistically assume Smi.
+      // TODO(srdjan): Check deopt reason to prevent repeated deoptimizations.
+      value_check = ic_data.AsUnaryClassChecksForCid(kSmiCid, target);
       return InlineSetIndexed(kind, target, call, receiver, token_pos,
                               value_check, entry, last);
     case MethodRecognizer::kInt32ArraySetIndexed:
-    case MethodRecognizer::kUint32ArraySetIndexed:
-      // Check that value is always smi or mint. We use Int32/Uint32 unboxing
-      // which can only deal unbox these values.
-      value_check = ic_data.AsUnaryClassChecksForArgNr(2);
-      if (!HasOnlySmiOrMint(value_check)) {
-        return false;
-      }
+    case MethodRecognizer::kUint32ArraySetIndexed: {
+      // Value check not needed for Int32 and Uint32 arrays because they
+      // implicitly contain unboxing instructions which check for right type.
+      ICData& value_check = ICData::Handle();
       return InlineSetIndexed(kind, target, call, receiver, token_pos,
                               value_check, entry, last);
+    }
     case MethodRecognizer::kInt64ArraySetIndexed:
       if (!ShouldInlineInt64ArrayOps()) {
         return false;
@@ -1442,33 +1436,22 @@
       if (!CanUnboxDouble()) {
         return false;
       }
-      // Check that value is always double.
-      if (!ArgIsAlways(kDoubleCid, ic_data, 2)) {
-        return false;
-      }
-      value_check = ic_data.AsUnaryClassChecksForArgNr(2);
+      value_check = ic_data.AsUnaryClassChecksForCid(kDoubleCid, target);
       return InlineSetIndexed(kind, target, call, receiver, token_pos,
                               value_check, entry, last);
     case MethodRecognizer::kFloat32x4ArraySetIndexed:
       if (!ShouldInlineSimd()) {
         return false;
       }
-      // Check that value is always a Float32x4.
-      if (!ArgIsAlways(kFloat32x4Cid, ic_data, 2)) {
-        return false;
-      }
-      value_check = ic_data.AsUnaryClassChecksForArgNr(2);
+      value_check = ic_data.AsUnaryClassChecksForCid(kFloat32x4Cid, target);
+
       return InlineSetIndexed(kind, target, call, receiver, token_pos,
                               value_check, entry, last);
     case MethodRecognizer::kFloat64x2ArraySetIndexed:
       if (!ShouldInlineSimd()) {
         return false;
       }
-      // Check that value is always a Float32x4.
-      if (!ArgIsAlways(kFloat64x2Cid, ic_data, 2)) {
-        return false;
-      }
-      value_check = ic_data.AsUnaryClassChecksForArgNr(2);
+      value_check = ic_data.AsUnaryClassChecksForCid(kFloat64x2Cid, target);
       return InlineSetIndexed(kind, target, call, receiver, token_pos,
                               value_check, entry, last);
     case MethodRecognizer::kByteArrayBaseGetInt8:
@@ -4534,18 +4517,6 @@
   if (InstanceCallNeedsClassCheck(instr, RawFunction::kImplicitSetter)) {
     AddReceiverCheck(instr);
   }
-  StoreBarrierType needs_store_barrier = kEmitStoreBarrier;
-  if (ArgIsAlways(kSmiCid, *instr->ic_data(), 1)) {
-    InsertBefore(instr,
-                 new(Z) CheckSmiInstr(
-                     new(Z) Value(instr->ArgumentAt(1)),
-                     instr->deopt_id(),
-                     instr->token_pos()),
-                 instr->env(),
-                 FlowGraph::kEffect);
-    needs_store_barrier = kNoStoreBarrier;
-  }
-
   if (field.guarded_cid() != kDynamicCid) {
     InsertBefore(instr,
                  new(Z) GuardFieldClassInstr(
@@ -4571,7 +4542,7 @@
       field,
       new(Z) Value(instr->ArgumentAt(0)),
       new(Z) Value(instr->ArgumentAt(1)),
-      needs_store_barrier,
+      kEmitStoreBarrier,
       instr->token_pos());
 
   if (store->IsUnboxedStore()) {
diff --git a/runtime/vm/instructions_ia32.cc b/runtime/vm/instructions_ia32.cc
index 4eb0c3c..4093e20 100644
--- a/runtime/vm/instructions_ia32.cc
+++ b/runtime/vm/instructions_ia32.cc
@@ -55,6 +55,17 @@
 }
 
 
+const int* ProloguePattern::pattern() const {
+  static const int kProloguePattern[kLengthInBytes] = { 0x55, 0x89, 0xe5 };
+  return kProloguePattern;
+}
+
+
+const int* SetFramePointerPattern::pattern() const {
+  static const int kFramePointerPattern[kLengthInBytes] = { 0x89, 0xe5 };
+  return kFramePointerPattern;
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/instructions_ia32.h b/runtime/vm/instructions_ia32.h
index 7f9f188..c536124 100644
--- a/runtime/vm/instructions_ia32.h
+++ b/runtime/vm/instructions_ia32.h
@@ -106,6 +106,33 @@
   static const int kLengthInBytes = 1;
 };
 
+
+// push ebp
+// mov ebp, esp
+class ProloguePattern : public InstructionPattern {
+ public:
+  explicit ProloguePattern(uword pc) : InstructionPattern(pc) {}
+
+  virtual const int* pattern() const;
+  virtual int pattern_length_in_bytes() const { return kLengthInBytes; }
+
+ private:
+  static const int kLengthInBytes = 3;
+};
+
+
+// mov ebp, esp
+class SetFramePointerPattern : public InstructionPattern {
+ public:
+  explicit SetFramePointerPattern(uword pc) : InstructionPattern(pc) {}
+
+  virtual const int* pattern() const;
+  virtual int pattern_length_in_bytes() const { return kLengthInBytes; }
+
+ private:
+  static const int kLengthInBytes = 2;
+};
+
 }  // namespace dart
 
 #endif  // VM_INSTRUCTIONS_IA32_H_
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index f4a0632..98ffcd9 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -79,6 +79,19 @@
   return kReturnPattern;
 }
 
+
+const int* ProloguePattern::pattern() const {
+  static const int kProloguePattern[kLengthInBytes] =
+      { 0x55, 0x48, 0x89, 0xe5 };
+  return kProloguePattern;
+}
+
+
+const int* SetFramePointerPattern::pattern() const {
+  static const int kFramePointerPattern[kLengthInBytes] = { 0x48, 0x89, 0xe5 };
+  return kFramePointerPattern;
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/instructions_x64.h b/runtime/vm/instructions_x64.h
index 0c0dc53..0d6bb08 100644
--- a/runtime/vm/instructions_x64.h
+++ b/runtime/vm/instructions_x64.h
@@ -112,6 +112,33 @@
   static const int kLengthInBytes = 1;
 };
 
+
+// push rbp
+// mov rbp, rsp
+class ProloguePattern : public InstructionPattern {
+ public:
+  explicit ProloguePattern(uword pc) : InstructionPattern(pc) {}
+
+  virtual const int* pattern() const;
+  virtual int pattern_length_in_bytes() const { return kLengthInBytes; }
+
+ private:
+  static const int kLengthInBytes = 4;
+};
+
+
+// mov rbp, rsp
+class SetFramePointerPattern : public InstructionPattern {
+ public:
+  explicit SetFramePointerPattern(uword pc) : InstructionPattern(pc) {}
+
+  virtual const int* pattern() const;
+  virtual int pattern_length_in_bytes() const { return kLengthInBytes; }
+
+ private:
+  static const int kLengthInBytes = 3;
+};
+
 }  // namespace dart
 
 #endif  // VM_INSTRUCTIONS_X64_H_
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 47e7dab..bd570f7 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -1257,6 +1257,18 @@
 }
 
 
+bool UnboxUint32Instr::CanDeoptimize() const {
+  ASSERT(is_truncating());
+  if ((value()->Type()->ToCid() == kSmiCid) ||
+      (value()->Type()->ToCid() == kMintCid)) {
+    return false;
+  }
+  // Check input value's range.
+  Range* value_range = value()->definition()->range();
+  return !RangeUtils::Fits(value_range, RangeBoundary::kRangeBoundaryInt64);
+}
+
+
 bool BinaryInt32OpInstr::CanDeoptimize() const {
   switch (op_kind()) {
     case Token::kBIT_AND:
@@ -2941,7 +2953,7 @@
   if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) {
     const Array& arguments_descriptor =
         Array::Handle(zone, ArgumentsDescriptor::New(ArgumentCount(),
-                                                        argument_names()));
+                                                     argument_names()));
     call_ic_data = compiler->GetOrAddInstanceCallICData(
         deopt_id(), function_name(), arguments_descriptor,
         checked_argument_count());
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 6290b00..1216a6a 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -4907,11 +4907,7 @@
     ASSERT(is_truncating());
   }
 
-  virtual bool CanDeoptimize() const {
-    ASSERT(is_truncating());
-    return (value()->Type()->ToCid() != kSmiCid)
-        && (value()->Type()->ToCid() != kMintCid);
-  }
+  virtual bool CanDeoptimize() const;
 
   virtual void InferRange(RangeAnalysis* analysis, Range* range);
 
@@ -6228,7 +6224,7 @@
 
   virtual Representation RequiredInputRepresentation(intptr_t idx) const {
     ASSERT((idx >= 0) && (idx < 4));
-    return kUnboxedUint32;
+    return kUnboxedInt32;
   }
 
   virtual intptr_t DeoptimizationTarget() const {
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index eac606c..2142327 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -2316,7 +2316,7 @@
                       R0,  // instance
                       R3,  // end address
                       R6,
-                      R8);
+                      R9);
   // R0: new object start as a tagged pointer.
   // R3: new object end address.
 
@@ -2333,7 +2333,7 @@
   // Initialize all array elements to raw_null.
   // R0: new object start as a tagged pointer.
   // R3: new object end address.
-  // R8: iterator which initially points to the start of the variable
+  // R9: iterator which initially points to the start of the variable
   // data area to be initialized.
   // R6: null
   if (num_elements > 0) {
@@ -2347,12 +2347,12 @@
       __ LoadImmediate(R7, 0x1);
 #endif  // DEBUG
     }
-    __ AddImmediate(R8, R0, sizeof(RawArray) - kHeapObjectTag);
+    __ AddImmediate(R9, R0, sizeof(RawArray) - kHeapObjectTag);
     if (array_size < (kInlineArraySize * kWordSize)) {
-      __ InitializeFieldsNoBarrierUnrolled(R0, R8, 0, num_elements * kWordSize,
+      __ InitializeFieldsNoBarrierUnrolled(R0, R9, 0, num_elements * kWordSize,
                                            R6, R7);
     } else {
-      __ InitializeFieldsNoBarrier(R0, R8, R3, R6, R7);
+      __ InitializeFieldsNoBarrier(R0, R9, R3, R6, R7);
     }
   }
   __ b(done);
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index 92c25d8..d6b8718 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -3310,6 +3310,17 @@
     __ SmiUntag(out, value);
   } else if (value_cid == kMintCid) {
     __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
+  } else if (!CanDeoptimize()) {
+    // Type information is not conclusive, but range analysis found
+    // the value to be in int64 range. Therefore it must be a smi
+    // or mint value.
+    ASSERT(is_truncating());
+    Label done;
+    __ SmiUntag(out, value);
+    __ TestImmediate(value, kSmiTagMask, PP);
+    __ b(&done, EQ);
+    __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
+    __ Bind(&done);
   } else {
     Label done;
     __ SmiUntag(out, value);
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 689f7e2..a7bad0a 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -3437,6 +3437,17 @@
     __ SmiUntag(value);
   } else if (value_cid == kMintCid) {
     __ movq(value, FieldAddress(value, Mint::value_offset()));
+  } else if (!CanDeoptimize()) {
+    // Type information is not conclusive, but range analysis found
+    // the value to be in int64 range. Therefore it must be a smi
+    // or mint value.
+    ASSERT(is_truncating());
+    Label done;
+    __ SmiUntag(value);
+    __ j(NOT_CARRY, &done, Assembler::kNearJump);
+    __ movq(value, Address(value, TIMES_2, Mint::value_offset()));
+    __ Bind(&done);
+    return;
   } else {
     Label done;
     // Optimistically untag value.
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 37ff3d7..71cf333 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -84,10 +84,10 @@
   TYPED_DATA_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
   GRAPH_TYPED_DATA_INTRINSICS_LIST(SETUP_FUNCTION);
 
-  // Setup all dart:profiler lib functions that can be intrinsified.
-  lib = Library::ProfilerLibrary();
+  // Setup all dart:developer lib functions that can be intrinsified.
+  lib = Library::DeveloperLibrary();
   ASSERT(!lib.IsNull());
-  PROFILER_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
+  DEVELOPER_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
 
 #undef SETUP_FUNCTION
 }
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 3cf09c5..f13f452 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -25,6 +25,7 @@
 // The R5, R4 registers can be destroyed only if there is no slow-path, i.e.
 // if the intrinsified method always executes a return.
 // The FP register should not be modified, because it is used by the profiler.
+// The THR register (see constants_arm.h) must be preserved.
 
 #define __ assembler->
 
@@ -576,10 +577,10 @@
   __ LoadImmediate(R7, 1);
   __ mov(R7, Operand(R7, LSL, R0));  // R7 <- 1 << R0
   __ sub(R7, R7, Operand(1));  // R7 <- R7 - 1
-  __ rsb(R8, R0, Operand(32));  // R8 <- 32 - R0
-  __ mov(R7, Operand(R7, LSL, R8));  // R7 <- R7 << R8
+  __ rsb(R9, R0, Operand(32));  // R9 <- 32 - R0
+  __ mov(R7, Operand(R7, LSL, R9));  // R7 <- R7 << R9
   __ and_(R7, R1, Operand(R7));  // R7 <- R7 & R1
-  __ mov(R7, Operand(R7, LSR, R8));  // R7 <- R7 >> R8
+  __ mov(R7, Operand(R7, LSR, R9));  // R7 <- R7 >> R9
   // Now R7 has the bits that fall off of R1 on a left shift.
   __ mov(R1, Operand(R1, LSL, R0));  // R1 gets the low bits.
 
@@ -817,12 +818,12 @@
   __ add(R6, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
   // R7 = &x_digits[x_used]
   __ add(R7, R6, Operand(R2, LSL, 1));
-  // R8 = &r_digits[1]
-  __ add(R8, R4, Operand(TypedData::data_offset() - kHeapObjectTag +
+  // R9 = &r_digits[1]
+  __ add(R9, R4, Operand(TypedData::data_offset() - kHeapObjectTag +
                          Bigint::kBytesPerDigit));
-  // R8 = &r_digits[x_used + n ~/ _DIGIT_BITS + 1]
+  // R9 = &r_digits[x_used + n ~/ _DIGIT_BITS + 1]
   __ add(R0, R0, Operand(R2, ASR, 1));
-  __ add(R8, R8, Operand(R0, LSL, 2));
+  __ add(R9, R9, Operand(R0, LSL, 2));
   // R3 = n % _DIGIT_BITS
   __ and_(R3, R5, Operand(31));
   // R2 = 32 - R3
@@ -832,11 +833,11 @@
   __ Bind(&loop);
   __ ldr(R0, Address(R7, -Bigint::kBytesPerDigit, Address::PreIndex));
   __ orr(R1, R1, Operand(R0, LSR, R2));
-  __ str(R1, Address(R8, -Bigint::kBytesPerDigit, Address::PreIndex));
+  __ str(R1, Address(R9, -Bigint::kBytesPerDigit, Address::PreIndex));
   __ mov(R1, Operand(R0, LSL, R3));
   __ teq(R7, Operand(R6));
   __ b(&loop, NE);
-  __ str(R1, Address(R8, -Bigint::kBytesPerDigit, Address::PreIndex));
+  __ str(R1, Address(R9, -Bigint::kBytesPerDigit, Address::PreIndex));
   // Returning Object::null() is not required, since this method is private.
   __ Ret();
 }
@@ -853,15 +854,15 @@
   __ SmiUntag(R5);
   // R0 = n ~/ _DIGIT_BITS
   __ Asr(R0, R5, Operand(5));
-  // R8 = &r_digits[0]
-  __ add(R8, R4, Operand(TypedData::data_offset() - kHeapObjectTag));
+  // R9 = &r_digits[0]
+  __ add(R9, R4, Operand(TypedData::data_offset() - kHeapObjectTag));
   // R7 = &x_digits[n ~/ _DIGIT_BITS]
   __ add(R7, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
   __ add(R7, R7, Operand(R0, LSL, 2));
   // R6 = &r_digits[x_used - n ~/ _DIGIT_BITS - 1]
   __ add(R0, R0, Operand(1));
   __ rsb(R0, R0, Operand(R2, ASR, 1));
-  __ add(R6, R8, Operand(R0, LSL, 2));
+  __ add(R6, R9, Operand(R0, LSL, 2));
   // R3 = n % _DIGIT_BITS
   __ and_(R3, R5, Operand(31));
   // R2 = 32 - R3
@@ -875,12 +876,12 @@
   __ Bind(&loop);
   __ ldr(R0, Address(R7, Bigint::kBytesPerDigit, Address::PostIndex));
   __ orr(R1, R1, Operand(R0, LSL, R2));
-  __ str(R1, Address(R8, Bigint::kBytesPerDigit, Address::PostIndex));
+  __ str(R1, Address(R9, Bigint::kBytesPerDigit, Address::PostIndex));
   __ mov(R1, Operand(R0, LSR, R3));
   __ Bind(&loop_entry);
-  __ teq(R8, Operand(R6));
+  __ teq(R9, Operand(R6));
   __ b(&loop, NE);
-  __ str(R1, Address(R8, 0));
+  __ str(R1, Address(R9, 0));
   // Returning Object::null() is not required, since this method is private.
   __ Ret();
 }
@@ -909,8 +910,8 @@
   // R7 = &digits[a_used >> 1], a_used is Smi.
   __ add(R7, R3, Operand(R4, LSL, 1));
 
-  // R8 = &digits[used >> 1], used is Smi.
-  __ add(R8, R3, Operand(R2, LSL, 1));
+  // R9 = &digits[used >> 1], used is Smi.
+  __ add(R9, R3, Operand(R2, LSL, 1));
 
   __ adds(R0, R0, Operand(0));  // carry flag = 0
   Label add_loop;
@@ -924,7 +925,7 @@
   __ b(&add_loop, NE);
 
   Label last_carry;
-  __ teq(R3, Operand(R8));  // Does not affect carry flag.
+  __ teq(R3, Operand(R9));  // Does not affect carry flag.
   __ b(&last_carry, EQ);  // If used - a_used == 0.
 
   Label carry_loop;
@@ -932,7 +933,7 @@
   // Loop used - a_used times, used - a_used > 0.
   __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
   __ adcs(R0, R0, Operand(0));
-  __ teq(R3, Operand(R8));  // Does not affect carry flag.
+  __ teq(R3, Operand(R9));  // Does not affect carry flag.
   __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&carry_loop, NE);
 
@@ -969,8 +970,8 @@
   // R7 = &digits[a_used >> 1], a_used is Smi.
   __ add(R7, R3, Operand(R4, LSL, 1));
 
-  // R8 = &digits[used >> 1], used is Smi.
-  __ add(R8, R3, Operand(R2, LSL, 1));
+  // R9 = &digits[used >> 1], used is Smi.
+  __ add(R9, R3, Operand(R2, LSL, 1));
 
   __ subs(R0, R0, Operand(0));  // carry flag = 1
   Label sub_loop;
@@ -984,7 +985,7 @@
   __ b(&sub_loop, NE);
 
   Label done;
-  __ teq(R3, Operand(R8));  // Does not affect carry flag.
+  __ teq(R3, Operand(R9));  // Does not affect carry flag.
   __ b(&done, EQ);  // If used - a_used == 0.
 
   Label carry_loop;
@@ -992,7 +993,7 @@
   // Loop used - a_used times, used - a_used > 0.
   __ ldr(R0, Address(R3, Bigint::kBytesPerDigit, Address::PostIndex));
   __ sbcs(R0, R0, Operand(0));
-  __ teq(R3, Operand(R8));  // Does not affect carry flag.
+  __ teq(R3, Operand(R9));  // Does not affect carry flag.
   __ str(R0, Address(R6, Bigint::kBytesPerDigit, Address::PostIndex));
   __ b(&carry_loop, NE);
 
@@ -1161,9 +1162,9 @@
 
   // int n = used - i - 1; while (--n >= 0) ...
   __ ldr(R0, Address(SP, 0 * kWordSize));  // used is Smi
-  __ sub(R8, R0, Operand(R2));
+  __ sub(R9, R0, Operand(R2));
   __ mov(R0, Operand(2));  // n = used - i - 2; if (n >= 0) ... while (--n >= 0)
-  __ rsbs(R8, R0, Operand(R8, ASR, kSmiTagSize));
+  __ rsbs(R9, R0, Operand(R9, ASR, kSmiTagSize));
 
   Label loop, done;
   __ b(&done, MI);
@@ -1174,7 +1175,7 @@
   // ajp: R5
   // c:   R7:R6
   // t:   R2:R1:R0 (not live at loop entry)
-  // n:   R8
+  // n:   R9
 
   // uint32_t xi = *xip++
   __ ldr(R2, Address(R4, Bigint::kBytesPerDigit, Address::PostIndex));
@@ -1197,7 +1198,7 @@
   __ str(R0, Address(R5, Bigint::kBytesPerDigit, Address::PostIndex));
 
   // while (--n >= 0)
-  __ subs(R8, R8, Operand(1));  // --n
+  __ subs(R9, R9, Operand(1));  // --n
   __ b(&loop, PL);
 
   __ Bind(&done);
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 7bc8fd6..b8783d0 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -814,14 +814,18 @@
   // static void _lsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
-  __ movl(EDI, Address(ESP, 4 * kWordSize));  // x_digits
-  __ movl(ECX, Address(ESP, 2 * kWordSize));  // n is Smi
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
+  __ movl(EDI, Address(ESP, 5 * kWordSize));  // x_digits
+  __ movl(ECX, Address(ESP, 3 * kWordSize));  // n is Smi
   __ SmiUntag(ECX);
-  __ movl(EBX, Address(ESP, 1 * kWordSize));  // r_digits
+  __ movl(EBX, Address(ESP, 2 * kWordSize));  // r_digits
   __ movl(ESI, ECX);
   __ sarl(ESI, Immediate(5));  // ESI = n ~/ _DIGIT_BITS.
   __ leal(EBX, FieldAddress(EBX, ESI, TIMES_4, TypedData::data_offset()));
-  __ movl(ESI, Address(ESP, 3 * kWordSize));  // x_used > 0, Smi.
+  __ movl(ESI, Address(ESP, 4 * kWordSize));  // x_used > 0, Smi.
   __ SmiUntag(ESI);
   __ decl(ESI);
   __ xorl(EAX, EAX);  // EAX = 0.
@@ -844,6 +848,9 @@
   __ Bind(&last);
   __ shldl(EDX, ESI, ECX);  // ESI == 0.
   __ movl(Address(EBX, 0), EDX);
+
+  // Restore THR and return.
+  __ popl(THR);
   // Returning Object::null() is not required, since this method is private.
   __ ret();
 }
@@ -853,13 +860,17 @@
   // static void _rsh(Uint32List x_digits, int x_used, int n,
   //                  Uint32List r_digits)
 
-  __ movl(EDI, Address(ESP, 4 * kWordSize));  // x_digits
-  __ movl(ECX, Address(ESP, 2 * kWordSize));  // n is Smi
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
+  __ movl(EDI, Address(ESP, 5 * kWordSize));  // x_digits
+  __ movl(ECX, Address(ESP, 3 * kWordSize));  // n is Smi
   __ SmiUntag(ECX);
-  __ movl(EBX, Address(ESP, 1 * kWordSize));  // r_digits
+  __ movl(EBX, Address(ESP, 2 * kWordSize));  // r_digits
   __ movl(EDX, ECX);
   __ sarl(EDX, Immediate(5));  // EDX = n ~/ _DIGIT_BITS.
-  __ movl(ESI, Address(ESP, 3 * kWordSize));  // x_used > 0, Smi.
+  __ movl(ESI, Address(ESP, 4 * kWordSize));  // x_used > 0, Smi.
   __ SmiUntag(ESI);
   __ decl(ESI);
   // EDI = &x_digits[x_used - 1].
@@ -883,6 +894,9 @@
   __ Bind(&last);
   __ shrdl(EDX, ESI, ECX);  // ESI == 0.
   __ movl(Address(EBX, 0), EDX);
+
+  // Restore THR and return.
+  __ popl(THR);
   // Returning Object::null() is not required, since this method is private.
   __ ret();
 }
@@ -893,13 +907,17 @@
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
 
-  __ movl(EDI, Address(ESP, 5 * kWordSize));  // digits
-  __ movl(EAX, Address(ESP, 4 * kWordSize));  // used is Smi
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
+  __ movl(EDI, Address(ESP, 6 * kWordSize));  // digits
+  __ movl(EAX, Address(ESP, 5 * kWordSize));  // used is Smi
   __ SmiUntag(EAX);  // used > 0.
-  __ movl(ESI, Address(ESP, 3 * kWordSize));  // a_digits
-  __ movl(ECX, Address(ESP, 2 * kWordSize));  // a_used is Smi
+  __ movl(ESI, Address(ESP, 4 * kWordSize));  // a_digits
+  __ movl(ECX, Address(ESP, 3 * kWordSize));  // a_used is Smi
   __ SmiUntag(ECX);  // a_used > 0.
-  __ movl(EBX, Address(ESP, 1 * kWordSize));  // r_digits
+  __ movl(EBX, Address(ESP, 2 * kWordSize));  // r_digits
 
   // Precompute 'used - a_used' now so that carry flag is not lost later.
   __ subl(EAX, ECX);
@@ -937,6 +955,8 @@
   __ adcl(EAX, Immediate(0));
   __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
 
+  // Restore THR and return.
+  __ popl(THR);
   // Returning Object::null() is not required, since this method is private.
   __ ret();
 }
@@ -947,13 +967,17 @@
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
 
-  __ movl(EDI, Address(ESP, 5 * kWordSize));  // digits
-  __ movl(EAX, Address(ESP, 4 * kWordSize));  // used is Smi
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
+  __ movl(EDI, Address(ESP, 6 * kWordSize));  // digits
+  __ movl(EAX, Address(ESP, 5 * kWordSize));  // used is Smi
   __ SmiUntag(EAX);  // used > 0.
-  __ movl(ESI, Address(ESP, 3 * kWordSize));  // a_digits
-  __ movl(ECX, Address(ESP, 2 * kWordSize));  // a_used is Smi
+  __ movl(ESI, Address(ESP, 4 * kWordSize));  // a_digits
+  __ movl(ECX, Address(ESP, 3 * kWordSize));  // a_used is Smi
   __ SmiUntag(ECX);  // a_used > 0.
-  __ movl(EBX, Address(ESP, 1 * kWordSize));  // r_digits
+  __ movl(EBX, Address(ESP, 2 * kWordSize));  // r_digits
 
   // Precompute 'used - a_used' now so that carry flag is not lost later.
   __ subl(EAX, ECX);
@@ -987,6 +1011,8 @@
   __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
 
   __ Bind(&done);
+  // Restore THR and return.
+  __ popl(THR);
   // Returning Object::null() is not required, since this method is private.
   __ ret();
 }
@@ -1033,14 +1059,18 @@
   __ SmiUntag(EDX);
   __ j(ZERO, &no_op, Assembler::kNearJump);
 
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
   // EDI = mip = &m_digits[i >> 1]
-  __ movl(EDI, Address(ESP, 5 * kWordSize));  // m_digits
-  __ movl(EAX, Address(ESP, 4 * kWordSize));  // i is Smi
+  __ movl(EDI, Address(ESP, 6 * kWordSize));  // m_digits
+  __ movl(EAX, Address(ESP, 5 * kWordSize));  // i is Smi
   __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset()));
 
   // ESI = ajp = &a_digits[j >> 1]
-  __ movl(ESI, Address(ESP, 3 * kWordSize));  // a_digits
-  __ movl(EAX, Address(ESP, 2 * kWordSize));  // j is Smi
+  __ movl(ESI, Address(ESP, 4 * kWordSize));  // a_digits
+  __ movl(EAX, Address(ESP, 3 * kWordSize));  // j is Smi
   __ leal(ESI, FieldAddress(ESI, EAX, TIMES_2, TypedData::data_offset()));
 
   // Save n
@@ -1099,6 +1129,8 @@
 
   __ Bind(&done);
   __ Drop(1);  // n
+  // Restore THR and return.
+  __ popl(THR);
 
   __ Bind(&no_op);
   __ movl(EAX, Immediate(Smi::RawValue(1)));  // One digit processed.
@@ -1145,8 +1177,12 @@
   __ j(EQUAL, &x_zero, Assembler::kNearJump);
   __ addl(EDI, Immediate(Bigint::kBytesPerDigit));
 
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
   // ESI = ajp = &a_digits[i]
-  __ movl(ESI, Address(ESP, 2 * kWordSize));  // a_digits
+  __ movl(ESI, Address(ESP, 3 * kWordSize));  // a_digits
   __ leal(ESI, FieldAddress(ESI, EAX, TIMES_4, TypedData::data_offset()));
 
   // EDX:EAX = t = x*x + *ajp
@@ -1160,8 +1196,8 @@
   __ addl(ESI, Immediate(Bigint::kBytesPerDigit));
 
   // int n = used - i - 1
-  __ movl(EAX, Address(ESP, 1 * kWordSize));  // used is Smi
-  __ subl(EAX, Address(ESP, 3 * kWordSize));  // i is Smi
+  __ movl(EAX, Address(ESP, 2 * kWordSize));  // used is Smi
+  __ subl(EAX, Address(ESP, 4 * kWordSize));  // i is Smi
   __ SmiUntag(EAX);
   __ decl(EAX);
   __ pushl(EAX);  // Save n on stack.
@@ -1226,7 +1262,9 @@
   __ movl(Address(ESI, 0), EAX);
   __ movl(Address(ESI, Bigint::kBytesPerDigit), EDX);
 
+  // Restore THR and return.
   __ Drop(3);
+  __ popl(THR);
   __ Bind(&x_zero);
   __ movl(EAX, Immediate(Smi::RawValue(1)));  // One digit processed.
   __ ret();
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index d0fa2bf..ec9fbd3 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1491,8 +1491,8 @@
 void Isolate::PrintJSON(JSONStream* stream, bool ref) {
   JSONObject jsobj(stream);
   jsobj.AddProperty("type", (ref ? "@Isolate" : "Isolate"));
-  jsobj.AddPropertyF("id", "isolates/%" Pd "",
-                     static_cast<intptr_t>(main_port()));
+  jsobj.AddFixedServiceId("isolates/%" Pd "",
+                          static_cast<intptr_t>(main_port()));
 
   jsobj.AddProperty("name", debugger_name());
   jsobj.AddPropertyF("number", "%" Pd "",
@@ -1512,7 +1512,7 @@
     }
   }
   {
-    JSONObject jsheap(&jsobj, "heaps");
+    JSONObject jsheap(&jsobj, "_heaps");
     heap()->PrintToJSONObject(Heap::kNew, &jsheap);
     heap()->PrintToJSONObject(Heap::kOld, &jsheap);
   }
@@ -1548,7 +1548,7 @@
 
   timer_list().PrintTimersToJSONProperty(&jsobj);
   {
-    JSONObject tagCounters(&jsobj, "tagCounters");
+    JSONObject tagCounters(&jsobj, "_tagCounters");
     vm_tag_counters()->PrintToJSONObject(&tagCounters);
   }
   if (object_store()->sticky_error() != Object::null()) {
@@ -1557,21 +1557,15 @@
     jsobj.AddProperty("error", error, false);
   }
 
-  bool is_io_enabled = false;
   {
     const GrowableObjectArray& libs =
         GrowableObjectArray::Handle(object_store()->libraries());
     intptr_t num_libs = libs.Length();
     Library& lib = Library::Handle();
-    String& name = String::Handle();
 
     JSONArray lib_array(&jsobj, "libraries");
     for (intptr_t i = 0; i < num_libs; i++) {
       lib ^= libs.At(i);
-      name = lib.name();
-      if (name.Equals(Symbols::DartIOLibName())) {
-        is_io_enabled = true;
-      }
       ASSERT(!lib.IsNull());
       lib_array.AddValue(lib);
     }
@@ -1580,12 +1574,6 @@
     JSONArray breakpoints(&jsobj, "breakpoints");
     debugger()->PrintBreakpointsToJSONArray(&breakpoints);
   }
-  {
-    JSONArray features_array(&jsobj, "features");
-    if (is_io_enabled) {
-      features_array.AddValue("io");
-    }
-  }
 }
 
 
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 9ee689f..57b23e9 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -167,7 +167,7 @@
 
   // A thread that operates on this isolate and may execute Dart code.
   // No other threads operating on this isolate may execute Dart code.
-  // TODO(koda): Remove after caching current thread in generated code.
+  // TODO(koda): Remove after pivoting to thread in NativeArguments.
   Thread* mutator_thread() {
     DEBUG_ASSERT(mutator_thread_ == NULL || IsIsolateOf(mutator_thread_));
     return mutator_thread_;
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 2ed62ef..efb1290 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -73,13 +73,13 @@
               isolate_name, method_);
     setup_time_micros_ = OS::GetCurrentTimeMicros();
   }
-  buffer_.Printf("{\"result\":");
+  buffer_.Printf("{\"json-rpc\":\"2.0\", \"result\":");
 }
 
 
 void JSONStream::SetupError() {
   buffer_.Clear();
-  buffer_.Printf("{\"error\":");
+  buffer_.Printf("{\"json-rpc\":\"2.0\", \"error\":");
 }
 
 
@@ -327,7 +327,7 @@
 }
 
 
-void JSONStream::PrintValue(SourceBreakpoint* bpt) {
+void JSONStream::PrintValue(Breakpoint* bpt) {
   PrintCommaIfNeeded();
   bpt->PrintJSON(this);
 }
@@ -357,9 +357,9 @@
 }
 
 
-void JSONStream::PrintServiceId(const char* name, const Object& o) {
+void JSONStream::PrintServiceId(const Object& o) {
   ASSERT(id_zone_ != NULL);
-  PrintProperty(name, id_zone_->GetServiceId(o));
+  PrintProperty("id", id_zone_->GetServiceId(o));
 }
 
 
@@ -415,7 +415,7 @@
 }
 
 
-void JSONStream::PrintProperty(const char* name, SourceBreakpoint* bpt) {
+void JSONStream::PrintProperty(const char* name, Breakpoint* bpt) {
   PrintPropertyName(name);
   PrintValue(bpt);
 }
@@ -558,6 +558,27 @@
 }
 
 
+void JSONObject::AddFixedServiceId(const char* format, ...) const {
+  // Mark that this id is fixed.
+  AddProperty("fixedId", true);
+  // Add the id property.
+  stream_->PrintPropertyName("id");
+  va_list args;
+  va_start(args, format);
+  intptr_t len = OS::VSNPrint(NULL, 0, format, args);
+  va_end(args);
+  char* p = reinterpret_cast<char*>(malloc(len+1));
+  va_start(args, format);
+  intptr_t len2 = OS::VSNPrint(p, len+1, format, args);
+  va_end(args);
+  ASSERT(len == len2);
+  stream_->buffer_.AddChar('"');
+  stream_->AddEscapedUTF8String(p);
+  stream_->buffer_.AddChar('"');
+  free(p);
+}
+
+
 void JSONObject::AddPropertyF(const char* name,
                               const char* format, ...) const {
   stream_->PrintPropertyName(name);
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index 3c3bc9c..5e0bf0c 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -22,7 +22,7 @@
 class Metric;
 class Object;
 class ServiceEvent;
-class SourceBreakpoint;
+class Breakpoint;
 class String;
 class Zone;
 
@@ -115,14 +115,14 @@
   void PrintValueNoEscape(const char* s);
   void PrintfValue(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
   void PrintValue(const Object& o, bool ref = true);
-  void PrintValue(SourceBreakpoint* bpt);
+  void PrintValue(Breakpoint* bpt);
   void PrintValue(const ServiceEvent* event);
   void PrintValue(Metric* metric);
   void PrintValue(MessageQueue* queue);
   void PrintValue(Isolate* isolate, bool ref = true);
   bool PrintValueStr(const String& s, intptr_t limit);
 
-  void PrintServiceId(const char* name, const Object& o);
+  void PrintServiceId(const Object& o);
   void PrintPropertyBool(const char* name, bool b);
   void PrintProperty(const char* name, intptr_t i);
   void PrintProperty64(const char* name, int64_t i);
@@ -135,7 +135,7 @@
   void PrintProperty(const char* name, const Object& o, bool ref = true);
 
   void PrintProperty(const char* name, const ServiceEvent* event);
-  void PrintProperty(const char* name, SourceBreakpoint* bpt);
+  void PrintProperty(const char* name, Breakpoint* bpt);
   void PrintProperty(const char* name, Metric* metric);
   void PrintProperty(const char* name, MessageQueue* queue);
   void PrintProperty(const char* name, Isolate* isolate);
@@ -181,10 +181,12 @@
     stream_->CloseObject();
   }
 
-  void AddServiceId(const char* name, const Object& o) const {
-    stream_->PrintServiceId(name, o);
+  void AddServiceId(const Object& o) const {
+    stream_->PrintServiceId(o);
   }
 
+  void AddFixedServiceId(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);
+
   void AddProperty(const char* name, bool b) const {
     stream_->PrintPropertyBool(name, b);
   }
@@ -214,7 +216,7 @@
   void AddProperty(const char* name, const ServiceEvent* event) const {
     stream_->PrintProperty(name, event);
   }
-  void AddProperty(const char* name, SourceBreakpoint* bpt) const {
+  void AddProperty(const char* name, Breakpoint* bpt) const {
     stream_->PrintProperty(name, bpt);
   }
   void AddProperty(const char* name, Metric* metric) const {
@@ -265,7 +267,7 @@
   void AddValue(Isolate* isolate, bool ref = true) const {
     stream_->PrintValue(isolate, ref);
   }
-  void AddValue(SourceBreakpoint* bpt) const {
+  void AddValue(Breakpoint* bpt) const {
     stream_->PrintValue(bpt);
   }
   void AddValue(const ServiceEvent* event) const {
diff --git a/runtime/vm/json_test.cc b/runtime/vm/json_test.cc
index b7c25da..d4bdf036 100644
--- a/runtime/vm/json_test.cc
+++ b/runtime/vm/json_test.cc
@@ -299,9 +299,11 @@
     JSONObject jsobj(&jsarr);
     jsobj.AddProperty("object_key", Object::Handle(Object::null()));
   }
-  EXPECT_STREQ("[{\"type\":\"@null\",\"id\":\"objects\\/null\","
+  EXPECT_STREQ("[{\"type\":\"@null\",\"fixedId\":true,"
+               "\"id\":\"objects\\/null\","
                "\"valueAsString\":\"null\"},"
-               "{\"object_key\":{\"type\":\"@null\",\"id\":\"objects\\/null\","
+               "{\"object_key\":{\"type\":\"@null\",\"fixedId\":true,"
+               "\"id\":\"objects\\/null\","
                "\"valueAsString\":\"null\"}}]",
                js.ToCString());
 }
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index 34e3b40..6a473dd 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -7,6 +7,7 @@
 #include "vm/dart.h"
 #include "vm/lockers.h"
 #include "vm/port.h"
+#include "vm/thread_interrupter.h"
 
 namespace dart {
 
@@ -145,6 +146,10 @@
   // If isolate() returns NULL StartIsolateScope does nothing.
   StartIsolateScope start_isolate(isolate());
 
+  // ThreadInterrupter may have gone to sleep waiting while waiting for
+  // an isolate to start handling messages.
+  ThreadInterrupter::WakeUp();
+
   // TODO(turnidge): Add assert that monitor_ is held here.
   bool result = true;
   Message::Priority min_priority = (allow_normal_messages && !paused()) ?
diff --git a/runtime/vm/method_recognizer.cc b/runtime/vm/method_recognizer.cc
index 1aff186..d0b941e 100644
--- a/runtime/vm/method_recognizer.cc
+++ b/runtime/vm/method_recognizer.cc
@@ -47,7 +47,7 @@
   libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
   libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
   libs.Add(&Library::ZoneHandle(Library::InternalLibrary()));
-  libs.Add(&Library::ZoneHandle(Library::ProfilerLibrary()));
+  libs.Add(&Library::ZoneHandle(Library::DeveloperLibrary()));
   Function& func = Function::Handle();
 
 #define SET_RECOGNIZED_KIND(class_name, function_name, enum_name, fp)          \
diff --git a/runtime/vm/method_recognizer.h b/runtime/vm/method_recognizer.h
index c6ad791..48c7c42 100644
--- a/runtime/vm/method_recognizer.h
+++ b/runtime/vm/method_recognizer.h
@@ -13,10 +13,10 @@
 // When adding a new function add a 0 as fingerprint, build and run to get the
 // correct fingerprint from the mismatch error.
 #define OTHER_RECOGNIZED_LIST(V)                                               \
-  V(::, identical, ObjectIdentical, 496869842)                                 \
-  V(ClassID, getID, ClassIDgetID, 1662520165)                                  \
-  V(Object, Object., ObjectConstructor, 1066669787)                            \
-  V(_List, ., ObjectArrayAllocate, 335347617)                                  \
+  V(::, identical, ObjectIdentical, 554128144)                                 \
+  V(ClassID, getID, ClassIDgetID, 535124072)                                   \
+  V(Object, Object., ObjectConstructor, 1066759160)                            \
+  V(_List, ., ObjectArrayAllocate, 850375012)                                  \
   V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 1541411498)                    \
   V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 1032404349)                  \
   V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 381073990)                   \
@@ -28,21 +28,21 @@
   V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1792407200)              \
   V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1338379857)          \
   V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 1469917805)              \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 783880753)                     \
-  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 499938872)                   \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1156009451)                  \
-  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 1239113233)                \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 2058780470)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 66201433)                  \
-  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 1823612342)                  \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1499236144)              \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1323416269)              \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 1301054599)          \
-  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 1651670367)              \
-  V(_StringBase, _interpolate, StringBaseInterpolate, 1503544722)              \
-  V(_IntegerImplementation, toDouble, IntegerToDouble, 1020333941)             \
-  V(_IntegerImplementation, _leftShiftWithMask32, IntegerLeftShiftWithMask32,  \
-      597111055)                                                               \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 1892735922)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 1608794041)                  \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 117380972)                   \
+  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 200484754)                 \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 1020151991)                  \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1175056602)                \
+  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 784983863)                   \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 460607665)               \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 284787790)               \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 262426120)           \
+  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 613041888)               \
+  V(_StringBase, _interpolate, StringBaseInterpolate, 1214901263)              \
+  V(_IntegerImplementation, toDouble, IntegerToDouble, 826404440)              \
+  V(_IntegerImplementation, _leftShiftWithMask32,                              \
+      IntegerLeftShiftWithMask32, 598958097)                                   \
   V(_Double, truncateToDouble, DoubleTruncate, 2117801967)                     \
   V(_Double, roundToDouble, DoubleRound, 2124216110)                           \
   V(_Double, floorToDouble, DoubleFloor, 968600699)                            \
@@ -54,22 +54,21 @@
   V(_Double, _div, DoubleDiv, 1201505037)                                      \
   V(::, sin, MathSin, 1741396147)                                              \
   V(::, cos, MathCos, 1951197905)                                              \
-  V(::, min, MathMin, 214919172)                                               \
-  V(::, max, MathMax, 989552054)                                               \
-  V(::, _doublePow, MathDoublePow, 275712742)                                  \
-  V(Float32x4, Float32x4., Float32x4Constructor, 137170840)                    \
-  V(Float32x4, Float32x4.zero, Float32x4Zero, 1336967908)                      \
-  V(Float32x4, Float32x4.splat, Float32x4Splat, 2001978631)                    \
-  V(Float32x4, Float32x4.fromInt32x4Bits, Float32x4FromInt32x4Bits,            \
-      1725843383)                                                              \
-  V(Float32x4, Float32x4.fromFloat64x2, Float32x4FromFloat64x2, 217874863)     \
+  V(::, min, MathMin, 478627534)                                               \
+  V(::, max, MathMax, 212291192)                                               \
+  V(::, _doublePow, MathDoublePow, 1286501289)                                 \
+  V(Float32x4, Float32x4., Float32x4Constructor, 1413513587)                   \
+  V(Float32x4, Float32x4.zero, Float32x4Zero, 865663495)                       \
+  V(Float32x4, Float32x4.splat, Float32x4Splat, 964312836)                     \
+  V(Float32x4, Float32x4.fromInt32x4Bits, Float32x4FromInt32x4Bits, 688177588) \
+  V(Float32x4, Float32x4.fromFloat64x2, Float32x4FromFloat64x2, 1327692716)    \
   V(_Float32x4, shuffle, Float32x4Shuffle, 1636488139)                         \
-  V(_Float32x4, shuffleMix, Float32x4ShuffleMix, 597555927)                    \
-  V(_Float32x4, get:x, Float32x4ShuffleX, 384880349)                           \
-  V(_Float32x4, get:y, Float32x4ShuffleY, 1398032569)                          \
-  V(_Float32x4, get:z, Float32x4ShuffleZ, 1178086232)                          \
-  V(_Float32x4, get:w, Float32x4ShuffleW, 480861630)                           \
-  V(_Float32x4, get:signMask, Float32x4GetSignMask, 630791302)                 \
+  V(_Float32x4, shuffleMix, Float32x4ShuffleMix, 654814229)                    \
+  V(_Float32x4, get:x, Float32x4ShuffleX, 384969722)                           \
+  V(_Float32x4, get:y, Float32x4ShuffleY, 1398121942)                          \
+  V(_Float32x4, get:z, Float32x4ShuffleZ, 1178175605)                          \
+  V(_Float32x4, get:w, Float32x4ShuffleW, 480951003)                           \
+  V(_Float32x4, get:signMask, Float32x4GetSignMask, 630880675)                 \
   V(_Float32x4, _cmpequal, Float32x4Equal, 571062952)                          \
   V(_Float32x4, _cmpgt, Float32x4GreaterThan, 1613543295)                      \
   V(_Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, 589402909)               \
@@ -84,225 +83,225 @@
   V(_Float32x4, _reciprocal, Float32x4Reciprocal, 739405237)                   \
   V(_Float32x4, _negate, Float32x4Negate, 445839777)                           \
   V(_Float32x4, _abs, Float32x4Absolute, 1152777608)                           \
-  V(_Float32x4, _clamp, Float32x4Clamp, 353415442)                             \
+  V(_Float32x4, _clamp, Float32x4Clamp, 410673744)                             \
   V(_Float32x4, withX, Float32x4WithX, 1446546696)                             \
   V(_Float32x4, withY, Float32x4WithY, 309844761)                              \
   V(_Float32x4, withZ, Float32x4WithZ, 971921505)                              \
   V(_Float32x4, withW, Float32x4WithW, 1759699726)                             \
-  V(Float64x2, Float64x2., Float64x2Constructor, 490465873)                    \
-  V(Float64x2, Float64x2.zero, Float64x2Zero, 1679669116)                      \
-  V(Float64x2, Float64x2.splat, Float64x2Splat, 2025058326)                    \
-  V(Float64x2, Float64x2.fromFloat32x4, Float64x2FromFloat32x4, 438009925)     \
-  V(_Float64x2, get:x, Float64x2GetX, 261073885)                               \
-  V(_Float64x2, get:y, Float64x2GetY, 1942287677)                              \
+  V(Float64x2, Float64x2., Float64x2Constructor, 1047027504)                   \
+  V(Float64x2, Float64x2.zero, Float64x2Zero, 1208364703)                      \
+  V(Float64x2, Float64x2.splat, Float64x2Splat, 987392531)                     \
+  V(Float64x2, Float64x2.fromFloat32x4, Float64x2FromFloat32x4, 1547827778)    \
+  V(_Float64x2, get:x, Float64x2GetX, 261163258)                               \
+  V(_Float64x2, get:y, Float64x2GetY, 1942377050)                              \
   V(_Float64x2, _negate, Float64x2Negate, 2133212774)                          \
   V(_Float64x2, abs, Float64x2Abs, 1224776282)                                 \
   V(_Float64x2, sqrt, Float64x2Sqrt, 1037569520)                               \
-  V(_Float64x2, get:signMask, Float64x2GetSignMask, 252966591)                 \
+  V(_Float64x2, get:signMask, Float64x2GetSignMask, 253055964)                 \
   V(_Float64x2, scale, Float64x2Scale, 1199438744)                             \
   V(_Float64x2, withX, Float64x2WithX, 1042725932)                             \
   V(_Float64x2, withY, Float64x2WithY, 1496958947)                             \
   V(_Float64x2, min, Float64x2Min, 485240583)                                  \
   V(_Float64x2, max, Float64x2Max, 2146148204)                                 \
-  V(Int32x4, Int32x4., Int32x4Constructor, 1194767693)                         \
-  V(Int32x4, Int32x4.bool, Int32x4BoolConstructor, 1052882565)                 \
-  V(Int32x4, Int32x4.fromFloat32x4Bits, Int32x4FromFloat32x4Bits,              \
-      1458284585)                                                              \
-  V(_Int32x4, get:flagX, Int32x4GetFlagX, 1077585029)                          \
-  V(_Int32x4, get:flagY, Int32x4GetFlagY, 779190075)                           \
-  V(_Int32x4, get:flagZ, Int32x4GetFlagZ, 181942074)                           \
-  V(_Int32x4, get:flagW, Int32x4GetFlagW, 977705325)                           \
-  V(_Int32x4, get:signMask, Int32x4GetSignMask, 1929301705)                    \
+  V(Int32x4, Int32x4., Int32x4Constructor, 323626792)                          \
+  V(Int32x4, Int32x4.bool, Int32x4BoolConstructor, 637206368)                  \
+  V(Int32x4, Int32x4.fromFloat32x4Bits, Int32x4FromFloat32x4Bits, 420618790)   \
+  V(_Int32x4, get:flagX, Int32x4GetFlagX, 1077674402)                          \
+  V(_Int32x4, get:flagY, Int32x4GetFlagY, 779279448)                           \
+  V(_Int32x4, get:flagZ, Int32x4GetFlagZ, 182031447)                           \
+  V(_Int32x4, get:flagW, Int32x4GetFlagW, 977794698)                           \
+  V(_Int32x4, get:signMask, Int32x4GetSignMask, 1929391078)                    \
   V(_Int32x4, shuffle, Int32x4Shuffle, 1870018702)                             \
-  V(_Int32x4, shuffleMix, Int32x4ShuffleMix, 967644870)                        \
-  V(_Int32x4, select, Int32x4Select, 1291364368)                               \
+  V(_Int32x4, shuffleMix, Int32x4ShuffleMix, 1024903172)                       \
+  V(_Int32x4, select, Int32x4Select, 1638081645)                               \
   V(_Int32x4, withFlagX, Int32x4WithFlagX, 467852789)                          \
   V(_Int32x4, withFlagY, Int32x4WithFlagY, 1903359978)                         \
   V(_Int32x4, withFlagZ, Int32x4WithFlagZ, 862460960)                          \
   V(_Int32x4, withFlagW, Int32x4WithFlagW, 1095242907)                         \
-  V(_Float32Array, [], Float32ArrayGetIndexed, 1535169225)                     \
-  V(_Float32Array, []=, Float32ArraySetIndexed, 626578817)                     \
-  V(_Int8Array, [], Int8ArrayGetIndexed, 138473967)                            \
-  V(_Int8Array, []=, Int8ArraySetIndexed, 1974948008)                          \
-  V(_Uint8ClampedArray, [], Uint8ClampedArrayGetIndexed, 900572864)            \
-  V(_Uint8ClampedArray, []=, Uint8ClampedArraySetIndexed, 1618616151)          \
-  V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed,       \
-    1375076880)                                                                \
-  V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed,      \
-    1734046173)                                                                \
-  V(_Int16Array, [], Int16ArrayGetIndexed, 2007660358)                         \
-  V(_Int16Array, []=, Int16ArraySetIndexed, 1816201356)                        \
-  V(_Uint16Array, [], Uint16ArrayGetIndexed, 1089984866)                       \
-  V(_Uint16Array, []=, Uint16ArraySetIndexed, 1478733345)                      \
-  V(_Int32Array, [], Int32ArrayGetIndexed, 1705827339)                         \
-  V(_Int32Array, []=, Int32ArraySetIndexed, 42548988)                          \
-  V(_Uint32Array, [], Uint32ArrayGetIndexed, 1251606959)                       \
-  V(_Uint32Array, []=, Uint32ArraySetIndexed, 35369746)                        \
-  V(_Int64Array, [], Int64ArrayGetIndexed, 123397249)                          \
-  V(_Int64Array, []=, Int64ArraySetIndexed, 1286315154)                        \
-  V(_Float32x4Array, [], Float32x4ArrayGetIndexed, 1291435540)                 \
-  V(_Float32x4Array, []=, Float32x4ArraySetIndexed, 993794277)                 \
-  V(_Int32x4Array, [], Int32x4ArrayGetIndexed, 1120121805)                     \
-  V(_Int32x4Array, []=, Int32x4ArraySetIndexed, 900060207)                     \
-  V(_Float64x2Array, [], Float64x2ArrayGetIndexed, 408038297)                  \
-  V(_Float64x2Array, []=, Float64x2ArraySetIndexed, 1277140175)                \
-  V(_Bigint, get:_neg, Bigint_getNeg, 1151543890)                              \
-  V(_Bigint, get:_used, Bigint_getUsed, 1308559334)                            \
-  V(_Bigint, get:_digits, Bigint_getDigits, 1408092463)                        \
+  V(_Float32Array, [], Float32ArrayGetIndexed, 275040752)                      \
+  V(_Float32Array, []=, Float32ArraySetIndexed, 157872912)                     \
+  V(_Int8Array, [], Int8ArrayGetIndexed, 1025829142)                           \
+  V(_Int8Array, []=, Int8ArraySetIndexed, 1696011449)                          \
+  V(_Uint8ClampedArray, [], Uint8ClampedArrayGetIndexed, 1787928039)           \
+  V(_Uint8ClampedArray, []=, Uint8ClampedArraySetIndexed, 1339679592)          \
+  V(_ExternalUint8ClampedArray, [],                                            \
+      ExternalUint8ClampedArrayGetIndexed, 114948407)                          \
+  V(_ExternalUint8ClampedArray, []=,                                           \
+      ExternalUint8ClampedArraySetIndexed, 1455109614)                         \
+  V(_Int16Array, [], Int16ArrayGetIndexed, 747531885)                          \
+  V(_Int16Array, []=, Int16ArraySetIndexed, 1537264797)                        \
+  V(_Uint16Array, [], Uint16ArrayGetIndexed, 1977340041)                       \
+  V(_Uint16Array, []=, Uint16ArraySetIndexed, 1199796786)                      \
+  V(_Int32Array, [], Int32ArrayGetIndexed, 445698866)                          \
+  V(_Int32Array, []=, Int32ArraySetIndexed, 1911096077)                        \
+  V(_Uint32Array, [], Uint32ArrayGetIndexed, 2138962134)                       \
+  V(_Uint32Array, []=, Uint32ArraySetIndexed, 1903916835)                      \
+  V(_Int64Array, [], Int64ArrayGetIndexed, 1010752424)                         \
+  V(_Int64Array, []=, Int64ArraySetIndexed, 1007378595)                        \
+  V(_Float32x4Array, [], Float32x4ArrayGetIndexed, 31307067)                   \
+  V(_Float32x4Array, []=, Float32x4ArraySetIndexed, 525088372)                 \
+  V(_Int32x4Array, [], Int32x4ArrayGetIndexed, 2007476980)                     \
+  V(_Int32x4Array, []=, Int32x4ArraySetIndexed, 431354302)                     \
+  V(_Float64x2Array, [], Float64x2ArrayGetIndexed, 1295393472)                 \
+  V(_Float64x2Array, []=, Float64x2ArraySetIndexed, 808434270)                 \
+  V(_Bigint, get:_neg, Bigint_getNeg, 1151633263)                              \
+  V(_Bigint, get:_used, Bigint_getUsed, 1308648707)                            \
+  V(_Bigint, get:_digits, Bigint_getDigits, 1408181836)                        \
 
 // List of intrinsics:
 // (class-name, function-name, intrinsification method, fingerprint).
 #define CORE_LIB_INTRINSIC_LIST(V)                                             \
-  V(_Smi, ~, Smi_bitNegate, 134149043)                                         \
-  V(_Smi, get:bitLength, Smi_bitLength, 869986288)                             \
-  V(_Bigint, _lsh, Bigint_lsh, 1318834243)                                     \
-  V(_Bigint, _rsh, Bigint_rsh, 1239668932)                                     \
-  V(_Bigint, _absAdd, Bigint_absAdd, 222437051)                                \
-  V(_Bigint, _absSub, Bigint_absSub, 599465997)                                \
-  V(_Bigint, _mulAdd, Bigint_mulAdd, 1696801459)                               \
-  V(_Bigint, _sqrAdd, Bigint_sqrAdd, 1937424317)                               \
-  V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 1873913198)           \
-  V(_Montgomery, _mulMod, Montgomery_mulMod, 2040316431)                       \
-  V(_Double, >, Double_greaterThan, 1538121903)                                \
-  V(_Double, >=, Double_greaterEqualThan, 1058495718)                          \
-  V(_Double, <, Double_lessThan, 62910596)                                     \
-  V(_Double, <=, Double_lessEqualThan, 1902937798)                             \
-  V(_Double, ==, Double_equal, 793601203)                                      \
-  V(_Double, +, Double_add, 655662995)                                         \
-  V(_Double, -, Double_sub, 486771820)                                         \
-  V(_Double, *, Double_mul, 343893321)                                         \
-  V(_Double, /, Double_div, 947349699)                                         \
-  V(_Double, get:isNaN, Double_getIsNaN, 843079824)                            \
-  V(_Double, get:isNegative, Double_getIsNegative, 1637905371)                 \
-  V(_Double, _mulFromInteger, Double_mulFromInteger, 1748815298)               \
-  V(_Double, .fromInteger, DoubleFromInteger, 803258435)                       \
-  V(_List, []=, ObjectArraySetIndexed, 1768442583)                             \
-  V(_GrowableList, .withData, GrowableArray_Allocate, 536409567)               \
-  V(_GrowableList, add, GrowableArray_add, 422087403)                          \
-  V(_JSSyntaxRegExp, _ExecuteMatch, JSRegExp_ExecuteMatch, 1654250896)         \
-  V(Object, ==, ObjectEquals, 1955975370)                                      \
-  V(_StringBase, get:hashCode, String_getHashCode, 2102936032)                 \
-  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 769493198)                    \
+  V(_Smi, ~, Smi_bitNegate, 221883538)                                         \
+  V(_Smi, get:bitLength, Smi_bitLength, 870075661)                             \
+  V(_Bigint, _lsh, Bigint_lsh, 1457834861)                                     \
+  V(_Bigint, _rsh, Bigint_rsh, 1619318930)                                     \
+  V(_Bigint, _absAdd, Bigint_absAdd, 1029882563)                               \
+  V(_Bigint, _absSub, Bigint_absSub, 1407667556)                               \
+  V(_Bigint, _mulAdd, Bigint_mulAdd, 1408994809)                               \
+  V(_Bigint, _sqrAdd, Bigint_sqrAdd, 2025116181)                               \
+  V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 919247767)            \
+  V(_Montgomery, _mulMod, Montgomery_mulMod, 401580778)                        \
+  V(_Double, >, Double_greaterThan, 1329424300)                                \
+  V(_Double, >=, Double_greaterEqualThan, 805805707)                           \
+  V(_Double, <, Double_lessThan, 1504529159)                                   \
+  V(_Double, <=, Double_lessEqualThan, 1650247787)                             \
+  V(_Double, ==, Double_equal, 1107327662)                                     \
+  V(_Double, +, Double_add, 957499569)                                         \
+  V(_Double, -, Double_sub, 788608394)                                         \
+  V(_Double, *, Double_mul, 645729895)                                         \
+  V(_Double, /, Double_div, 1249186273)                                        \
+  V(_Double, get:isNaN, Double_getIsNaN, 843169197)                            \
+  V(_Double, get:isNegative, Double_getIsNegative, 1637994744)                 \
+  V(_Double, _mulFromInteger, Double_mulFromInteger, 63390017)                 \
+  V(_Double, .fromInteger, DoubleFromInteger, 213717920)                       \
+  V(_List, []=, ObjectArraySetIndexed, 527521746)                              \
+  V(_GrowableList, .withData, GrowableArray_Allocate, 2094352700)              \
+  V(_GrowableList, add, GrowableArray_add, 1675959698)                         \
+  V(_JSSyntaxRegExp, _ExecuteMatch, JSRegExp_ExecuteMatch, 1711509198)         \
+  V(Object, ==, ObjectEquals, 409406570)                                       \
+  V(_StringBase, get:hashCode, String_getHashCode, 2103025405)                 \
+  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 780870414)                    \
   V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 397735324)                  \
-  V(_StringBase, [], StringBaseCharAt, 1107537364)                             \
-  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 1111867720)       \
+  V(_StringBase, [], StringBaseCharAt, 408544820)                              \
+  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 1111957093)       \
   V(_OneByteString, _substringUncheckedNative,                                 \
-      OneByteString_substringUnchecked, 1527498975)                            \
-  V(_OneByteString, _setAt, OneByteStringSetAt, 819138038)                     \
-  V(_OneByteString, _allocate, OneByteString_allocate, 227962559)              \
-  V(_OneByteString, ==, OneByteString_equality, 1857083054)                    \
-  V(_TwoByteString, ==, TwoByteString_equality, 1081185720)                    \
+      OneByteString_substringUnchecked, 1584757277)                            \
+  V(_OneByteString, _setAt, OneByteStringSetAt, 1927993207)                    \
+  V(_OneByteString, _allocate, OneByteString_allocate, 1248050114)             \
+  V(_OneByteString, ==, OneByteString_equality, 1151307249)                    \
+  V(_TwoByteString, ==, TwoByteString_equality, 375409915)                     \
 
 
 #define CORE_INTEGER_LIB_INTRINSIC_LIST(V)                                     \
   V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger,           \
     438687793)                                                                 \
-  V(_IntegerImplementation, +, Integer_add, 1324179652)                        \
+  V(_IntegerImplementation, +, Integer_add, 6890122)                           \
   V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger,           \
     562800077)                                                                 \
-  V(_IntegerImplementation, -, Integer_sub, 494872517)                         \
+  V(_IntegerImplementation, -, Integer_sub, 1325066635)                        \
   V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger,           \
     67891834)                                                                  \
-  V(_IntegerImplementation, *, Integer_mul, 463313062)                         \
+  V(_IntegerImplementation, *, Integer_mul, 1293507180)                        \
   V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger,     \
     93478264)                                                                  \
-  V(_IntegerImplementation, ~/, Integer_truncDivide, 300412283)                \
-  V(_IntegerImplementation, unary-, Integer_negate, 1899613736)                \
+  V(_IntegerImplementation, ~/, Integer_truncDivide, 1401079912)               \
+  V(_IntegerImplementation, unary-, Integer_negate, 1992904169)                \
   V(_IntegerImplementation, _bitAndFromInteger,                                \
     Integer_bitAndFromInteger, 504496713)                                      \
-  V(_IntegerImplementation, &, Integer_bitAnd, 1471812911)                     \
+  V(_IntegerImplementation, &, Integer_bitAnd, 154523381)                      \
   V(_IntegerImplementation, _bitOrFromInteger,                                 \
     Integer_bitOrFromInteger, 1763728073)                                      \
-  V(_IntegerImplementation, |, Integer_bitOr, 149206765)                       \
+  V(_IntegerImplementation, |, Integer_bitOr, 979400883)                       \
   V(_IntegerImplementation, _bitXorFromInteger,                                \
     Integer_bitXorFromInteger, 281425907)                                      \
-  V(_IntegerImplementation, ^, Integer_bitXor, 922906510)                      \
+  V(_IntegerImplementation, ^, Integer_bitXor, 1753100628)                     \
   V(_IntegerImplementation,                                                    \
     _greaterThanFromInteger,                                                   \
     Integer_greaterThanFromInt, 787426822)                                     \
-  V(_IntegerImplementation, >, Integer_greaterThan, 1226840498)                \
-  V(_IntegerImplementation, ==, Integer_equal, 1155579943)                     \
+  V(_IntegerImplementation, >, Integer_greaterThan, 871319346)                 \
+  V(_IntegerImplementation, ==, Integer_equal, 150126631)                      \
   V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger,           \
     1790821042)                                                                \
-  V(_IntegerImplementation, <, Integer_lessThan, 555566388)                    \
-  V(_IntegerImplementation, <=, Integer_lessEqualThan, 1161964406)             \
-  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 317522326)           \
-  V(_IntegerImplementation, <<, Integer_shl, 1479333073)                       \
-  V(_IntegerImplementation, >>, Integer_sar, 1310672722)                       \
+  V(_IntegerImplementation, <, Integer_lessThan, 1997184951)                   \
+  V(_IntegerImplementation, <=, Integer_lessEqualThan, 909274395)              \
+  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 64832315)            \
+  V(_IntegerImplementation, <<, Integer_shl, 162043543)                        \
+  V(_IntegerImplementation, >>, Integer_sar, 2140866840)                       \
   V(_Double, toInt, DoubleToInteger, 1547535151)
 
 
 #define MATH_LIB_INTRINSIC_LIST(V)                                             \
   V(::, sqrt, MathSqrt, 101545548)                                             \
-  V(_Random, _nextState, Random_nextState, 84519862)                           \
+  V(_Random, _nextState, Random_nextState, 170407315)                          \
 
 
 #define TYPED_DATA_LIB_INTRINSIC_LIST(V)                                       \
-  V(_Int8Array, _new, TypedData_Int8Array_new, 1490161004)                     \
-  V(_Uint8Array, _new, TypedData_Uint8Array_new, 212211297)                    \
-  V(_Uint8ClampedArray, _new, TypedData_Uint8ClampedArray_new, 1066441853)     \
-  V(_Int16Array, _new, TypedData_Int16Array_new, 72086552)                     \
-  V(_Uint16Array, _new, TypedData_Uint16Array_new, 529525586)                  \
-  V(_Int32Array, _new, TypedData_Int32Array_new, 2065356233)                   \
-  V(_Uint32Array, _new, TypedData_Uint32Array_new, 350335670)                  \
-  V(_Int64Array, _new, TypedData_Int64Array_new, 1639531103)                   \
-  V(_Uint64Array, _new, TypedData_Uint64Array_new, 1975347888)                 \
-  V(_Float32Array, _new, TypedData_Float32Array_new, 917766665)                \
-  V(_Float64Array, _new, TypedData_Float64Array_new, 985384871)                \
-  V(_Float32x4Array, _new, TypedData_Float32x4Array_new, 936668603)            \
-  V(_Int32x4Array, _new, TypedData_Int32x4Array_new, 836387418)                \
-  V(_Float64x2Array, _new, TypedData_Float64x2Array_new, 1847004265)           \
-  V(_Int8Array, ., TypedData_Int8Array_factory, 1234236264)                    \
-  V(_Uint8Array, ., TypedData_Uint8Array_factory, 89436950)                    \
-  V(_Uint8ClampedArray, ., TypedData_Uint8ClampedArray_factory, 2114336727)    \
-  V(_Int16Array, ., TypedData_Int16Array_factory, 779429598)                   \
-  V(_Uint16Array, ., TypedData_Uint16Array_factory, 351653952)                 \
-  V(_Int32Array, ., TypedData_Int32Array_factory, 1909366715)                  \
-  V(_Uint32Array, ., TypedData_Uint32Array_factory, 32690110)                  \
-  V(_Int64Array, ., TypedData_Int64Array_factory, 1987760123)                  \
-  V(_Uint64Array, ., TypedData_Uint64Array_factory, 1205087814)                \
-  V(_Float32Array, ., TypedData_Float32Array_factory, 1988570712)              \
-  V(_Float64Array, ., TypedData_Float64Array_factory, 77468920)                \
-  V(_Float32x4Array, ., TypedData_Float32x4Array_factory, 953075137)           \
-  V(_Int32x4Array, ., TypedData_Int32x4Array_factory, 1983535209)              \
-  V(_Float64x2Array, ., TypedData_Float64x2Array_factory, 346534719)           \
+  V(_Int8Array, _new, TypedData_Int8Array_new, 362764911)                      \
+  V(_Uint8Array, _new, TypedData_Uint8Array_new, 1232298852)                   \
+  V(_Uint8ClampedArray, _new, TypedData_Uint8ClampedArray_new, 2086529408)     \
+  V(_Int16Array, _new, TypedData_Int16Array_new, 1092174107)                   \
+  V(_Uint16Array, _new, TypedData_Uint16Array_new, 1549613141)                 \
+  V(_Int32Array, _new, TypedData_Int32Array_new, 937960140)                    \
+  V(_Uint32Array, _new, TypedData_Uint32Array_new, 1370423225)                 \
+  V(_Int64Array, _new, TypedData_Int64Array_new, 512135010)                    \
+  V(_Uint64Array, _new, TypedData_Uint64Array_new, 847951795)                  \
+  V(_Float32Array, _new, TypedData_Float32Array_new, 1937854220)               \
+  V(_Float64Array, _new, TypedData_Float64Array_new, 2005472426)               \
+  V(_Float32x4Array, _new, TypedData_Float32x4Array_new, 1956756158)           \
+  V(_Int32x4Array, _new, TypedData_Int32x4Array_new, 1856474973)               \
+  V(_Float64x2Array, _new, TypedData_Float64x2Array_new, 719608172)            \
+  V(_Int8Array, ., TypedData_Int8Array_factory, 439914696)                     \
+  V(_Uint8Array, ., TypedData_Uint8Array_factory, 1442599030)                  \
+  V(_Uint8ClampedArray, ., TypedData_Uint8ClampedArray_factory, 1320015159)    \
+  V(_Int16Array, ., TypedData_Int16Array_factory, 2132591678)                  \
+  V(_Uint16Array, ., TypedData_Uint16Array_factory, 1704816032)                \
+  V(_Int32Array, ., TypedData_Int32Array_factory, 1115045147)                  \
+  V(_Uint32Array, ., TypedData_Uint32Array_factory, 1385852190)                \
+  V(_Int64Array, ., TypedData_Int64Array_factory, 1193438555)                  \
+  V(_Uint64Array, ., TypedData_Uint64Array_factory, 410766246)                 \
+  V(_Float32Array, ., TypedData_Float32Array_factory, 1194249144)              \
+  V(_Float64Array, ., TypedData_Float64Array_factory, 1430631000)              \
+  V(_Float32x4Array, ., TypedData_Float32x4Array_factory, 158753569)           \
+  V(_Int32x4Array, ., TypedData_Int32x4Array_factory, 1189213641)              \
+  V(_Float64x2Array, ., TypedData_Float64x2Array_factory, 1699696799)          \
 
 #define GRAPH_TYPED_DATA_INTRINSICS_LIST(V) \
-  V(_Uint8Array, [], Uint8ArrayGetIndexed, 934520139)                          \
-  V(_Uint8Array, []=, Uint8ArraySetIndexed, 1193298978)                        \
-  V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 937149728)          \
-  V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 1465870106)        \
-  V(_Float64Array, []=, Float64ArraySetIndexed, 1400622753)                    \
-  V(_Float64Array, [], Float64ArrayGetIndexed, 1330768796)                     \
-  V(_TypedList, get:length, TypedDataLength, 522595148)                        \
+  V(_Uint8Array, [], Uint8ArrayGetIndexed, 1821875314)                         \
+  V(_Uint8Array, []=, Uint8ArraySetIndexed, 914362419)                         \
+  V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 1824504903)         \
+  V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 1186933547)        \
+  V(_Float64Array, []=, Float64ArraySetIndexed, 931916848)                     \
+  V(_Float64Array, [], Float64ArrayGetIndexed, 70640323)                       \
+  V(_TypedList, get:length, TypedDataLength, 522684521)                        \
 
 #define GRAPH_CORE_INTRINSICS_LIST(V)                                          \
-  V(_List, get:length, ObjectArrayLength, 1181382520)                          \
-  V(_List, [], ObjectArrayGetIndexed, 390939163)                               \
-  V(_ImmutableList, get:length, ImmutableArrayLength, 274947518)               \
-  V(_ImmutableList, [], ImmutableArrayGetIndexed, 1585504028)                  \
-  V(_GrowableList, get:length, GrowableArrayLength, 778534898)                 \
-  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 555169866)            \
-  V(_GrowableList, _setData, GrowableArraySetData, 1722254196)                 \
-  V(_GrowableList, _setLength, GrowableArraySetLength, 1832199634)             \
-  V(_GrowableList, [], GrowableArrayGetIndexed, 514434920)                     \
-  V(_GrowableList, []=, GrowableArraySetIndexed, 1698264861)                   \
-  V(_StringBase, get:length, StringBaseLength, 784429419)                      \
+  V(_List, get:length, ObjectArrayLength, 1181471893)                          \
+  V(_List, [], ObjectArrayGetIndexed, 1839430267)                              \
+  V(_ImmutableList, get:length, ImmutableArrayLength, 275036891)               \
+  V(_ImmutableList, [], ImmutableArrayGetIndexed, 886511484)                   \
+  V(_GrowableList, get:length, GrowableArrayLength, 778624271)                 \
+  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 555259239)            \
+  V(_GrowableList, _setData, GrowableArraySetData, 508234257)                  \
+  V(_GrowableList, _setLength, GrowableArraySetLength, 618179695)              \
+  V(_GrowableList, [], GrowableArrayGetIndexed, 1962926024)                    \
+  V(_GrowableList, []=, GrowableArraySetIndexed, 457344024)                    \
+  V(_StringBase, get:length, StringBaseLength, 784518792)                      \
 
 #define GRAPH_INTRINSICS_LIST(V)                                               \
   GRAPH_CORE_INTRINSICS_LIST(V)                                                \
   GRAPH_TYPED_DATA_INTRINSICS_LIST(V)                                          \
 
-#define PROFILER_LIB_INTRINSIC_LIST(V)                                         \
-  V(_UserTag, makeCurrent, UserTag_makeCurrent, 370414636)                     \
-  V(::, _getDefaultTag, UserTag_defaultTag, 1159885970)                        \
-  V(::, _getCurrentTag, Profiler_getCurrentTag, 1182126114)                    \
+#define DEVELOPER_LIB_INTRINSIC_LIST(V)                                        \
+  V(_UserTag, makeCurrent, UserTag_makeCurrent, 788201614)                     \
+  V(::, _getDefaultTag, UserTag_defaultTag, 1080704381)                        \
+  V(::, _getCurrentTag, Profiler_getCurrentTag, 2048029229)                    \
 
 #define ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V)                                  \
   CORE_LIB_INTRINSIC_LIST(V)                                                   \
+  DEVELOPER_LIB_INTRINSIC_LIST(V)                                              \
   MATH_LIB_INTRINSIC_LIST(V)                                                   \
   TYPED_DATA_LIB_INTRINSIC_LIST(V)                                             \
-  PROFILER_LIB_INTRINSIC_LIST(V)
+
 
 #define ALL_INTRINSICS_LIST(V)                                                 \
   ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V)                                        \
@@ -315,104 +314,104 @@
 
 // A list of core function that should always be inlined.
 #define INLINE_WHITE_LIST(V)                                                   \
-  V(Object, ==, ObjectEquals, 1955975370)                                      \
-  V(_List, get:length, ObjectArrayLength, 1181382520)                          \
-  V(_ImmutableList, get:length, ImmutableArrayLength, 274947518)               \
-  V(_TypedList, get:length, TypedDataLength, 522595148)                        \
-  V(_GrowableList, get:length, GrowableArrayLength, 778534898)                 \
-  V(_GrowableList, add, GrowableListAdd, 422087403)                            \
-  V(_GrowableList, removeLast, GrowableListRemoveLast, 1285719639)             \
-  V(_StringBase, get:length, StringBaseLength, 784429419)                      \
-  V(ListIterator, moveNext, ListIteratorMoveNext, 1001265875)                  \
-  V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 890839431)   \
-  V(_GrowableList, get:iterator, GrowableArrayIterator, 1663047580)            \
-  V(_GrowableList, forEach, GrowableArrayForEach, 605873384)                   \
-  V(_List, ., ObjectArrayAllocate, 335347617)                                  \
-  V(_List, [], ObjectArrayGetIndexed, 390939163)                               \
-  V(_List, []=, ObjectArraySetIndexed, 1768442583)                             \
-  V(ListMixin, get:isEmpty, ListMixinIsEmpty, 2102252776)                      \
-  V(_List, get:iterator, ObjectArrayIterator, 308726049)                       \
-  V(_List, forEach, ObjectArrayForEach, 1720909126)                            \
-  V(_List, _slice, ObjectArraySlice, 1738717516)                               \
-  V(_ImmutableList, get:iterator, ImmutableArrayIterator, 212198431)           \
-  V(_ImmutableList, forEach, ImmutableArrayForEach, 1192041734)                \
-  V(_ImmutableList, [], ImmutableArrayGetIndexed, 1585504028)                  \
-  V(_GrowableList, [], GrowableArrayGetIndexed, 514434920)                     \
-  V(_GrowableList, []=, GrowableArraySetIndexed, 1698264861)                   \
-  V(_Float32Array, [], Float32ArrayGetIndexed, 1535169225)                     \
-  V(_Float32Array, []=, Float32ArraySetIndexed, 626578817)                     \
-  V(_Float64Array, [], Float64ArrayGetIndexed, 1330768796)                     \
-  V(_Float64Array, []=, Float64ArraySetIndexed, 1400622753)                    \
-  V(_Int8Array, [], Int8ArrayGetIndexed, 138473967)                            \
-  V(_Int8Array, []=, Int8ArraySetIndexed, 1974948008)                          \
-  V(_Uint8Array, [], Uint8ArrayGetIndexed, 934520139)                          \
-  V(_Uint8Array, []=, Uint8ArraySetIndexed, 1193298978)                        \
-  V(_Uint8ClampedArray, [], Uint8ClampedArrayGetIndexed, 900572864)            \
-  V(_Uint8ClampedArray, []=, Uint8ClampedArraySetIndexed, 1618616151)          \
-  V(_Uint16Array, [], Uint16ArrayGetIndexed, 1089984866)                       \
-  V(_Uint16Array, []=, Uint16ArraySetIndexed, 1478733345)                      \
-  V(_Int16Array, [], Int16ArrayGetIndexed, 2007660358)                         \
-  V(_Int16Array, []=, Int16ArraySetIndexed, 1816201356)                        \
-  V(_Int32Array, [], Int32ArrayGetIndexed, 1705827339)                         \
-  V(_Int32Array, []=, Int32ArraySetIndexed, 42548988)                          \
-  V(_Int64Array, [], Int64ArrayGetIndexed, 123397249)                          \
-  V(_Int64Array, []=, Int64ArraySetIndexed, 1286315154)                        \
-  V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 2146871134)                 \
-  V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 1262816136)                \
-  V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 231994143)                    \
-  V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 919877023)                   \
-  V(_ByteDataView, setInt8, ByteDataViewSetInt8, 809949404)                    \
-  V(_ByteDataView, setUint8, ByteDataViewSetUint8, 206282345)                  \
-  V(_ByteDataView, setInt16, ByteDataViewSetInt16, 989487799)                  \
-  V(_ByteDataView, setUint16, ByteDataViewSetUint16, 1118155962)               \
-  V(_ByteDataView, setInt32, ByteDataViewSetInt32, 1955213160)                 \
-  V(_ByteDataView, setUint32, ByteDataViewSetUint32, 284405389)                \
-  V(_ByteDataView, setInt64, ByteDataViewSetInt64, 486916661)                  \
-  V(_ByteDataView, setUint64, ByteDataViewSetUint64, 1432663320)               \
-  V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 344976311)              \
-  V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 1480166018)             \
-  V(_ByteDataView, getInt8, ByteDataViewGetInt8, 1383732403)                   \
-  V(_ByteDataView, getUint8, ByteDataViewGetUint8, 806641537)                  \
-  V(_ByteDataView, getInt16, ByteDataViewGetInt16, 76281079)                   \
-  V(_ByteDataView, getUint16, ByteDataViewGetUint16, 1136415701)               \
-  V(_ByteDataView, getInt32, ByteDataViewGetInt32, 865549439)                  \
-  V(_ByteDataView, getUint32, ByteDataViewGetUint32, 760435927)                \
-  V(_ByteDataView, getInt64, ByteDataViewGetInt64, 364361487)                  \
-  V(_ByteDataView, getUint64, ByteDataViewGetUint64, 565678407)                \
-  V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 1979131043)             \
-  V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 164756117)              \
+  V(Object, ==, ObjectEquals, 409406570)                                       \
+  V(_List, get:length, ObjectArrayLength, 1181471893)                          \
+  V(_ImmutableList, get:length, ImmutableArrayLength, 275036891)               \
+  V(_TypedList, get:length, TypedDataLength, 522684521)                        \
+  V(_GrowableList, get:length, GrowableArrayLength, 778624271)                 \
+  V(_GrowableList, add, GrowableListAdd, 1675959698)                           \
+  V(_GrowableList, removeLast, GrowableListRemoveLast, 1687341910)             \
+  V(_StringBase, get:length, StringBaseLength, 784518792)                      \
+  V(ListIterator, moveNext, ListIteratorMoveNext, 1698922708)                  \
+  V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 53548649)    \
+  V(_GrowableList, get:iterator, GrowableArrayIterator, 830391682)             \
+  V(_GrowableList, forEach, GrowableArrayForEach, 792224678)                   \
+  V(_List, ., ObjectArrayAllocate, 850375012)                                  \
+  V(_List, [], ObjectArrayGetIndexed, 1839430267)                              \
+  V(_List, []=, ObjectArraySetIndexed, 527521746)                              \
+  V(ListMixin, get:isEmpty, ListMixinIsEmpty, 40656674)                        \
+  V(_List, get:iterator, ObjectArrayIterator, 1623553799)                      \
+  V(_List, forEach, ObjectArrayForEach, 1840334181)                            \
+  V(_List, _slice, ObjectArraySlice, 1370223553)                               \
+  V(_ImmutableList, get:iterator, ImmutableArrayIterator, 1527026181)          \
+  V(_ImmutableList, forEach, ImmutableArrayForEach, 1311466789)                \
+  V(_ImmutableList, [], ImmutableArrayGetIndexed, 886511484)                   \
+  V(_GrowableList, [], GrowableArrayGetIndexed, 1962926024)                    \
+  V(_GrowableList, []=, GrowableArraySetIndexed, 457344024)                    \
+  V(_Float32Array, [], Float32ArrayGetIndexed, 275040752)                      \
+  V(_Float32Array, []=, Float32ArraySetIndexed, 157872912)                     \
+  V(_Float64Array, [], Float64ArrayGetIndexed, 70640323)                       \
+  V(_Float64Array, []=, Float64ArraySetIndexed, 931916848)                     \
+  V(_Int8Array, [], Int8ArrayGetIndexed, 1025829142)                           \
+  V(_Int8Array, []=, Int8ArraySetIndexed, 1696011449)                          \
+  V(_Uint8Array, [], Uint8ArrayGetIndexed, 1821875314)                         \
+  V(_Uint8Array, []=, Uint8ArraySetIndexed, 914362419)                         \
+  V(_Uint8ClampedArray, [], Uint8ClampedArrayGetIndexed, 1787928039)           \
+  V(_Uint8ClampedArray, []=, Uint8ClampedArraySetIndexed, 1339679592)          \
+  V(_Uint16Array, [], Uint16ArrayGetIndexed, 1977340041)                       \
+  V(_Uint16Array, []=, Uint16ArraySetIndexed, 1199796786)                      \
+  V(_Int16Array, [], Int16ArrayGetIndexed, 747531885)                          \
+  V(_Int16Array, []=, Int16ArraySetIndexed, 1537264797)                        \
+  V(_Int32Array, [], Int32ArrayGetIndexed, 445698866)                          \
+  V(_Int32Array, []=, Int32ArraySetIndexed, 1911096077)                        \
+  V(_Int64Array, [], Int64ArrayGetIndexed, 1010752424)                         \
+  V(_Int64Array, []=, Int64ArraySetIndexed, 1007378595)                        \
+  V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 1590194821)                 \
+  V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 1468172313)                \
+  V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 1822801478)                   \
+  V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 1125233200)                  \
+  V(_ByteDataView, setInt8, ByteDataViewSetInt8, 1157522735)                   \
+  V(_ByteDataView, setUint8, ByteDataViewSetUint8, 553855676)                  \
+  V(_ByteDataView, setInt16, ByteDataViewSetInt16, 2093298369)                 \
+  V(_ByteDataView, setUint16, ByteDataViewSetUint16, 74482884)                 \
+  V(_ByteDataView, setInt32, ByteDataViewSetInt32, 911540082)                  \
+  V(_ByteDataView, setUint32, ByteDataViewSetUint32, 1388215959)               \
+  V(_ByteDataView, setInt64, ByteDataViewSetInt64, 1590727231)                 \
+  V(_ByteDataView, setUint64, ByteDataViewSetUint64, 388990242)                \
+  V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 1599158058)             \
+  V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 586864117)              \
+  V(_ByteDataView, getInt8, ByteDataViewGetInt8, 1627121016)                   \
+  V(_ByteDataView, getUint8, ByteDataViewGetUint8, 1050030150)                 \
+  V(_ByteDataView, getInt16, ByteDataViewGetInt16, 891399987)                  \
+  V(_ByteDataView, getUint16, ByteDataViewGetUint16, 206709785)                \
+  V(_ByteDataView, getInt32, ByteDataViewGetInt32, 1680668347)                 \
+  V(_ByteDataView, getUint32, ByteDataViewGetUint32, 1978213659)               \
+  V(_ByteDataView, getInt64, ByteDataViewGetInt64, 1179480395)                 \
+  V(_ByteDataView, getUint64, ByteDataViewGetUint64, 1783456139)               \
+  V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 354362094)              \
+  V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 687470816)              \
   V(::, asin, MathASin, 1651042633)                                            \
   V(::, acos, MathACos, 1139647090)                                            \
   V(::, atan, MathATan, 1668754384)                                            \
-  V(::, atan2, MathATan2, 1845649456)                                          \
+  V(::, atan2, MathATan2, 1931713076)                                          \
   V(::, cos, MathCos, 1951197905)                                              \
   V(::, exp, MathExp, 1809210829)                                              \
   V(::, log, MathLog, 1620336448)                                              \
-  V(::, max, MathMax, 989552054)                                               \
-  V(::, min, MathMin, 214919172)                                               \
-  V(::, pow, MathPow, 1381728863)                                              \
+  V(::, max, MathMax, 212291192)                                               \
+  V(::, min, MathMin, 478627534)                                               \
+  V(::, pow, MathPow, 582475257)                                               \
   V(::, sin, MathSin, 1741396147)                                              \
   V(::, sqrt, MathSqrt, 101545548)                                             \
   V(::, tan, MathTan, 982072809)                                               \
-  V(Lists, copy, ListsCopy, 605584668)                                         \
-  V(_Bigint, get:_neg, Bigint_getNeg, 1151543890)                              \
-  V(_Bigint, get:_used, Bigint_getUsed, 1308559334)                            \
-  V(_Bigint, get:_digits, Bigint_getDigits, 1408092463)                        \
+  V(Lists, copy, ListsCopy, 618211805)                                         \
+  V(_Bigint, get:_neg, Bigint_getNeg, 1151633263)                              \
+  V(_Bigint, get:_used, Bigint_getUsed, 1308648707)                            \
+  V(_Bigint, get:_digits, Bigint_getDigits, 1408181836)                        \
 
 // A list of core function that should never be inlined.
 #define INLINE_BLACK_LIST(V)                                                   \
-  V(_Bigint, _lsh, Bigint_lsh, 1318834243)                                     \
-  V(_Bigint, _rsh, Bigint_rsh, 1239668932)                                     \
-  V(_Bigint, _absAdd, Bigint_absAdd, 222437051)                                \
-  V(_Bigint, _absSub, Bigint_absSub, 599465997)                                \
-  V(_Bigint, _mulAdd, Bigint_mulAdd, 1696801459)                               \
-  V(_Bigint, _sqrAdd, Bigint_sqrAdd, 1937424317)                               \
-  V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 1873913198)           \
-  V(_Montgomery, _mulMod, Montgomery_mulMod, 2040316431)                       \
+  V(_Bigint, _lsh, Bigint_lsh, 1457834861)                                     \
+  V(_Bigint, _rsh, Bigint_rsh, 1619318930)                                     \
+  V(_Bigint, _absAdd, Bigint_absAdd, 1029882563)                               \
+  V(_Bigint, _absSub, Bigint_absSub, 1407667556)                               \
+  V(_Bigint, _mulAdd, Bigint_mulAdd, 1408994809)                               \
+  V(_Bigint, _sqrAdd, Bigint_sqrAdd, 2025116181)                               \
+  V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 919247767)            \
+  V(_Montgomery, _mulMod, Montgomery_mulMod, 401580778)                        \
 
 // A list of core functions that internally dispatch based on received id.
 #define POLYMORPHIC_TARGET_LIST(V)                                             \
-  V(_StringBase, [], StringBaseCharAt, 1107537364)                             \
+  V(_StringBase, [], StringBaseCharAt, 408544820)                              \
   V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 397735324)                  \
   V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 1541411498)                    \
   V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 1032404349)                  \
@@ -424,16 +423,16 @@
   V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1792407200)              \
   V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1338379857)          \
   V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 1469917805)              \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 783880753)                     \
-  V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 499938872)                    \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1156009451)                  \
-  V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 1239113233)                 \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 2058780470)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 66201433)                  \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1499236144)              \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1323416269)              \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 1301054599)          \
-  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 1651670367)              \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 1892735922)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 1608794041)                   \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 117380972)                   \
+  V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 200484754)                  \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 1020151991)                  \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1175056602)                \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 460607665)               \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 284787790)               \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 262426120)           \
+  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 613041888)               \
 
 // Forward declarations.
 class Function;
diff --git a/runtime/vm/metrics.cc b/runtime/vm/metrics.cc
index 2e768b5..0e04e6b 100644
--- a/runtime/vm/metrics.cc
+++ b/runtime/vm/metrics.cc
@@ -82,9 +82,9 @@
   obj.AddProperty("description", description_);
   obj.AddProperty("unit", UnitString(unit()));
   if (isolate_ == NULL) {
-    obj.AddPropertyF("id", "vm/metrics/%s", name_);
+    obj.AddFixedServiceId("vm/metrics/%s", name_);
   } else {
-    obj.AddPropertyF("id", "metrics/native/%s", name_);
+    obj.AddFixedServiceId("metrics/native/%s", name_);
   }
   // TODO(johnmccutchan): Overflow?
   double value_as_double = static_cast<double>(Value());
diff --git a/runtime/vm/metrics_test.cc b/runtime/vm/metrics_test.cc
index 69fe545..6750a41 100644
--- a/runtime/vm/metrics_test.cc
+++ b/runtime/vm/metrics_test.cc
@@ -56,7 +56,7 @@
   const char* json = js.ToCString();
   EXPECT_STREQ("{\"type\":\"Counter\",\"name\":\"a.b.c\",\"description\":"
                "\"foobar\",\"unit\":\"byte\","
-               "\"id\":\"metrics\\/native\\/a.b.c\""
+               "\"fixedId\":true,\"id\":\"metrics\\/native\\/a.b.c\""
                ",\"value\":99.000000}", json);
 }
 
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 26fcb5c..8f64388 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -20,10 +20,10 @@
 
 // Forward declarations.
 class BootstrapNatives;
-class Isolate;
 class Object;
 class RawObject;
 class Simulator;
+class Thread;
 
 #if defined(TESTING) || defined(DEBUG)
 
@@ -85,7 +85,7 @@
 // subclass of ValueObject.
 class NativeArguments {
  public:
-  Isolate* isolate() const { return isolate_; }
+  Thread* thread() const { return thread_; }
   int ArgCount() const { return ArgcBits::decode(argc_tag_); }
 
   RawObject* ArgAt(int index) const {
@@ -127,8 +127,8 @@
     *retval_ = value.raw();
   }
 
-  static intptr_t isolate_offset() {
-    return OFFSET_OF(NativeArguments, isolate_);
+  static intptr_t thread_offset() {
+    return OFFSET_OF(NativeArguments, thread_);
   }
   static intptr_t argc_tag_offset() {
     return OFFSET_OF(NativeArguments, argc_tag_);
@@ -221,7 +221,7 @@
     return 0;
   }
 
-  Isolate* isolate_;  // Current isolate pointer.
+  Thread* thread_;  // Current thread pointer.
   int argc_tag_;  // Encodes argument count and invoked native call type.
   RawObject*(*argv_)[];  // Pointer to an array of arguments to runtime call.
   RawObject** retval_;  // Pointer to the return value area.
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index dccecce..39d9dcc 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -88,7 +88,7 @@
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   /* Tell MemorySanitizer 'arguments' is initialized by generated code. */
   MSAN_UNPOISON(arguments, sizeof(*arguments));
-  Isolate* isolate = arguments->isolate();
+  Isolate* isolate = arguments->thread()->isolate();
 
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index 3db849c..45dd5c9 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -51,10 +51,9 @@
     ASSERT(arguments->NativeArgCount() == argument_count);                     \
     TRACE_NATIVE_CALL("%s", ""#name);                                          \
     {                                                                          \
-      Isolate* isolate = arguments->isolate();                                 \
-      /* TODO(koda): Pivot from Isolate to Thread in NativeArguments. */       \
-      Thread* thread = isolate->mutator_thread();                              \
+      Thread* thread = arguments->thread();                                    \
       ASSERT(thread == Thread::Current());                                     \
+      Isolate* isolate = thread->isolate();                                    \
       StackZone zone(isolate);                                                 \
       SET_NATIVE_RETVAL(arguments,                                             \
                         DN_Helper##name(isolate,                               \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 3d282a8..674a65a 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -601,6 +601,17 @@
   isolate->object_store()->set_one_byte_string_class(cls);
   cls = Class::NewStringClass(kTwoByteStringCid);
   isolate->object_store()->set_two_byte_string_class(cls);
+  cls = Class::New<Mint>();
+  isolate->object_store()->set_mint_class(cls);
+  cls = Class::New<Bigint>();
+  isolate->object_store()->set_bigint_class(cls);
+  cls = Class::New<Double>();
+  isolate->object_store()->set_double_class(cls);
+
+  // Ensure that class kExternalTypedDataUint8ArrayCid is registered as we
+  // need it when reading in the token stream of bootstrap classes in the VM
+  // isolate.
+  Class::NewExternalTypedDataClass(kExternalTypedDataUint8ArrayCid);
 
   // Allocate and initialize the empty_array instance.
   {
@@ -1223,19 +1234,19 @@
   RegisterPrivateClass(cls, Symbols::_LinkedHashMap(), lib);
   pending_classes.Add(cls);
 
-  // Pre-register the profiler library so we can place the vm class
+  // Pre-register the developer library so we can place the vm class
   // UserTag there rather than the core library.
-  lib = Library::LookupLibrary(Symbols::DartProfiler());
+  lib = Library::LookupLibrary(Symbols::DartDeveloper());
   if (lib.IsNull()) {
-    lib = Library::NewLibraryHelper(Symbols::DartProfiler(), true);
+    lib = Library::NewLibraryHelper(Symbols::DartDeveloper(), true);
     lib.SetLoadRequested();
     lib.Register();
-    object_store->set_bootstrap_library(ObjectStore::kProfiler, lib);
+    object_store->set_bootstrap_library(ObjectStore::kDeveloper, lib);
   }
   ASSERT(!lib.IsNull());
-  ASSERT(lib.raw() == Library::ProfilerLibrary());
+  ASSERT(lib.raw() == Library::DeveloperLibrary());
 
-  lib = Library::LookupLibrary(Symbols::DartProfiler());
+  lib = Library::LookupLibrary(Symbols::DartDeveloper());
   ASSERT(!lib.IsNull());
   cls = Class::New<UserTag>();
   RegisterPrivateClass(cls, Symbols::_UserTag(), lib);
@@ -1598,7 +1609,7 @@
   if (IsNull()) {
     JSONObject jsobj(stream);
     AddTypeProperties(&jsobj, "null", JSONType(), ref);
-    jsobj.AddProperty("id", "objects/null");
+    jsobj.AddFixedServiceId("objects/null");
     jsobj.AddProperty("valueAsString", "null");
     if (!ref) {
       const Class& cls = Class::Handle(this->clazz());
@@ -1614,7 +1625,7 @@
 void Object::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "Object", JSONType(), ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   if (ref) {
     return;
   }
@@ -1676,7 +1687,8 @@
                             intptr_t size,
                             Heap::Space space) {
   ASSERT(Utils::IsAligned(size, kObjectAlignment));
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   ASSERT(isolate->no_callback_scope_depth() == 0);
   Heap* heap = isolate->heap();
 
@@ -1686,7 +1698,7 @@
     // into dart code or allocating any code.
     const Instance& exception =
         Instance::Handle(isolate->object_store()->out_of_memory());
-    Exceptions::Throw(isolate, exception);
+    Exceptions::Throw(thread, exception);
     UNREACHABLE();
   }
   if (space == Heap::kNew) {
@@ -4102,7 +4114,7 @@
     return;
   }
   AddTypeProperties(&jsobj, "Class", JSONType(), ref);
-  jsobj.AddPropertyF("id", "classes/%" Pd "", id());
+  jsobj.AddFixedServiceId("classes/%" Pd "", id());
   const String& user_name = String::Handle(PrettyName());
   const String& vm_name = String::Handle(Name());
   AddNameProperties(&jsobj, user_name, vm_name);
@@ -4432,7 +4444,7 @@
   const Array& table = Array::Handle(object_store->canonical_type_arguments());
   ASSERT(table.Length() > 0);
   AddTypeProperties(&jsobj, "TypeArguments", JSONType(), ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   const String& user_name = String::Handle(PrettyName());
   const String& vm_name = String::Handle(Name());
   AddNameProperties(&jsobj, user_name, vm_name);
@@ -6837,22 +6849,22 @@
   }
   if (id != -1) {
     ASSERT(selector != NULL);
-    jsobj.AddPropertyF("id", "classes/%" Pd "/%s/%" Pd "",
-                              cls.id(), selector, id);
+    jsobj.AddFixedServiceId("classes/%" Pd "/%s/%" Pd "",
+                            cls.id(), selector, id);
     return;
   }
   // Regular functions known to their owner use their name (percent-encoded).
   String& name = String::Handle(f.name());
   if (cls.LookupFunction(name) == f.raw()) {
     name = String::EncodeIRI(name);
-    jsobj.AddPropertyF("id", "classes/%" Pd "/functions/%s",
-                              cls.id(), name.ToCString());
+    jsobj.AddFixedServiceId("classes/%" Pd "/functions/%s",
+                            cls.id(), name.ToCString());
     return;
   }
   // Oddball functions (not known to their owner) fall back to use the object
   // id ring. Current known examples are signature functions of closures
   // and stubs like 'megamorphic_miss'.
-  jsobj.AddServiceId("id", f);
+  jsobj.AddServiceId(f);
 }
 
 
@@ -7214,7 +7226,7 @@
   ASSERT(id >= 0);
   intptr_t cid = cls.id();
   AddTypeProperties(&jsobj, "Field", JSONType(), ref);
-  jsobj.AddPropertyF("id", "classes/%" Pd "/fields/%" Pd "", cid, id);
+  jsobj.AddFixedServiceId("classes/%" Pd "/fields/%" Pd "", cid, id);
   const String& user_name = String::Handle(PrettyName());
   const String& vm_name = String::Handle(name());
   AddNameProperties(&jsobj, user_name, vm_name);
@@ -8001,7 +8013,7 @@
   AddTypeProperties(&jsobj, "Object", JSONType(), ref);
   // TODO(johnmccutchan): Generate a stable id. TokenStreams hang off
   // a Script object but do not have a back reference to generate a stable id.
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   if (ref) {
     return;
   }
@@ -8533,16 +8545,17 @@
 void Script::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "Script", JSONType(), ref);
-  const String& name = String::Handle(url());
-  ASSERT(!name.IsNull());
-  const String& encoded_url = String::Handle(String::EncodeIRI(name));
-  ASSERT(!encoded_url.IsNull());
+  const String& uri = String::Handle(url());
+  ASSERT(!uri.IsNull());
+  const String& encoded_uri = String::Handle(String::EncodeIRI(uri));
+  ASSERT(!encoded_uri.IsNull());
   const Library& lib = Library::Handle(FindLibrary());
+  // TODO(rmacnak): This can fail for eval scripts. Use a ring-id for those.
   intptr_t lib_index = (lib.IsNull()) ? -1 : lib.index();
-  jsobj.AddPropertyF("id", "libraries/%" Pd "/scripts/%s",
-      lib_index, encoded_url.ToCString());
-  jsobj.AddPropertyStr("name", name);
-  jsobj.AddProperty("kind", GetKindAsCString());
+  jsobj.AddFixedServiceId("libraries/%" Pd "/scripts/%s",
+      lib_index, encoded_uri.ToCString());
+  jsobj.AddPropertyStr("uri", uri);
+  jsobj.AddProperty("_kind", GetKindAsCString());
   if (ref) {
     return;
   }
@@ -9643,19 +9656,8 @@
   // as a static function of the class.
   Class& top_level_class = Class::Handle();
   Array& top_level_classes = Array::Handle(anonymous_classes());
-  if (top_level_classes.Length() > 0) {
-    top_level_class ^= top_level_classes.At(0);
-  } else {
-    // A library may have no top-level classes if it has no top-level
-    // variables or methods.
-    Script& script = Script::Handle(Script::New(Symbols::Empty(),
-                                                Symbols::Empty(),
-                                                RawScript::kSourceTag));
-    top_level_class = Class::New(Symbols::TopLevel(), script, 0);
-    top_level_class.set_is_finalized();
-    top_level_class.set_library(*this);
-    AddAnonymousClass(top_level_class);
-  }
+  ASSERT(top_level_classes.Length() > 0);
+  top_level_class ^= top_level_classes.At(0);
   ASSERT(top_level_class.is_finalized());
   return top_level_class.Evaluate(expr, param_names, param_values);
 }
@@ -9894,10 +9896,10 @@
   ASSERT(id >= 0);
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "Library", JSONType(), ref);
-  jsobj.AddPropertyF("id", "libraries/%" Pd "", id);
+  jsobj.AddFixedServiceId("libraries/%" Pd "", id);
   jsobj.AddProperty("name", library_name);
   const String& library_url = String::Handle(url());
-  jsobj.AddPropertyStr("url", library_url);
+  jsobj.AddPropertyStr("uri", library_url);
   if (ref) {
     return;
   }
@@ -10486,12 +10488,12 @@
   POLYMORPHIC_TARGET_LIST(CHECK_FINGERPRINTS);
 
   all_libs.Clear();
-  all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
-  MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
+  all_libs.Add(&Library::ZoneHandle(Library::DeveloperLibrary()));
+  DEVELOPER_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
 
   all_libs.Clear();
-  all_libs.Add(&Library::ZoneHandle(Library::ProfilerLibrary()));
-  PROFILER_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
+  all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
+  MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
 
   all_libs.Clear();
   all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
@@ -10702,7 +10704,7 @@
   AddTypeProperties(jsobj, "Object", JSONType(), ref);
   // TODO(johnmccutchan): Generate a stable id. PcDescriptors hang off a Code
   // object but do not have a back reference to generate an ID.
-  jsobj->AddServiceId("id", *this);
+  jsobj->AddServiceId(*this);
   if (ref) {
     return;
   }
@@ -10983,7 +10985,7 @@
   AddTypeProperties(&jsobj, "Object", JSONType(), ref);
   // TODO(johnmccutchan): Generate a stable id. LocalVarDescriptors hang off
   // a Code object but do not have a back reference to generate an ID.
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   if (ref) {
     return;
   }
@@ -11732,6 +11734,18 @@
 }
 
 
+RawICData* ICData::AsUnaryClassChecksForCid(
+    intptr_t cid, const Function& target) const {
+  ASSERT(!IsNull());
+  const intptr_t kNumArgsTested = 1;
+  ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested));
+
+  // Copy count so that we copy the state "count == 0" vs "count > 0".
+  result.AddReceiverCheck(cid, target, GetCountAt(0));
+  return result.raw();
+}
+
+
 RawICData* ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const {
   ASSERT(!IsNull());
   ASSERT(NumArgsTested() > arg_nr);
@@ -11740,12 +11754,7 @@
     return raw();
   }
   const intptr_t kNumArgsTested = 1;
-  ICData& result = ICData::Handle(ICData::New(
-      Function::Handle(owner()),
-      String::Handle(target_name()),
-      Array::Handle(arguments_descriptor()),
-      deopt_id(),
-      kNumArgsTested));
+  ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested));
   const intptr_t len = NumberOfChecks();
   for (intptr_t i = 0; i < len; i++) {
     const intptr_t class_id = GetClassIdAt(i, arg_nr);
@@ -11773,8 +11782,6 @@
                               count);
     }
   }
-  // Copy deoptimization reasons.
-  result.SetDeoptReasons(DeoptReasons());
 
   return result.raw();
 }
@@ -11897,6 +11904,19 @@
 }
 
 
+RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) {
+  const ICData& result = ICData::Handle(ICData::New(
+      Function::Handle(from.owner()),
+      String::Handle(from.target_name()),
+      Array::Handle(from.arguments_descriptor()),
+      from.deopt_id(),
+      num_args_tested));
+  // Copy deoptimization reasons.
+  result.SetDeoptReasons(from.DeoptReasons());
+  return result.raw();
+}
+
+
 void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const {
   Object::PrintJSONImpl(stream, ref);
 }
@@ -12281,15 +12301,68 @@
 }
 
 
-void Code::set_inlined_intervals(const Array& value) const {
-  ASSERT(value.IsOld());
-  StorePointer(&raw_ptr()->inlined_intervals_, value.raw());
+void Code::SetPrologueOffset(intptr_t offset) const {
+  ASSERT(offset >= 0);
+  StoreSmi(
+      reinterpret_cast<RawSmi* const *>(&raw_ptr()->return_address_metadata_),
+      Smi::New(offset));
 }
 
 
-void Code::set_inlined_id_to_function(const Array& value) const {
+intptr_t Code::GetPrologueOffset() const {
+  const Object& object = Object::Handle(raw_ptr()->return_address_metadata_);
+  // In the future we may put something other than a smi in
+  // |return_address_metadata_|.
+  if (object.IsNull() || !object.IsSmi()) {
+    return -1;
+  }
+  return Smi::Cast(object).Value();
+}
+
+
+RawArray* Code::GetInlinedIntervals() const {
+  const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
+  if (metadata.IsNull()) {
+    return metadata.raw();
+  }
+  return reinterpret_cast<RawArray*>(
+      metadata.At(RawCode::kInlinedIntervalsIndex));
+}
+
+
+void Code::SetInlinedIntervals(const Array& value) const {
+  if (raw_ptr()->inlined_metadata_ == Array::null()) {
+    StorePointer(&raw_ptr()->inlined_metadata_,
+                 Array::New(RawCode::kInlinedMetadataSize, Heap::kOld));
+  }
+  const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
+  ASSERT(!metadata.IsNull());
+  ASSERT(metadata.IsOld());
   ASSERT(value.IsOld());
-  StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw());
+  metadata.SetAt(RawCode::kInlinedIntervalsIndex, value);
+}
+
+
+RawArray* Code::GetInlinedIdToFunction() const {
+  const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
+  if (metadata.IsNull()) {
+    return metadata.raw();
+  }
+  return reinterpret_cast<RawArray*>(
+      metadata.At(RawCode::kInlinedIdToFunctionIndex));
+}
+
+
+void Code::SetInlinedIdToFunction(const Array& value) const {
+  if (raw_ptr()->inlined_metadata_ == Array::null()) {
+    StorePointer(&raw_ptr()->inlined_metadata_,
+                 Array::New(RawCode::kInlinedMetadataSize, Heap::kOld));
+  }
+  const Array& metadata = Array::Handle(raw_ptr()->inlined_metadata_);
+  ASSERT(!metadata.IsNull());
+  ASSERT(metadata.IsOld());
+  ASSERT(value.IsOld());
+  metadata.SetAt(RawCode::kInlinedIdToFunctionIndex, value);
 }
 
 
@@ -12395,6 +12468,13 @@
     }
   }
   code.set_comments(assembler->GetCodeComments());
+  if (assembler->prologue_offset() >= 0) {
+    code.SetPrologueOffset(assembler->prologue_offset());
+  } else {
+    // No prologue was ever entered, optimistically assume nothing was ever
+    // pushed onto the stack.
+    code.SetPrologueOffset(assembler->CodeSize());
+  }
   INC_STAT(Isolate::Current(),
            total_code_size, code.comments().comments_.Length());
   return code.raw();
@@ -12582,8 +12662,9 @@
 void Code::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "Code", JSONType(), ref);
-  jsobj.AddPropertyF("id", "code/%" Px64"-%" Px "", compile_timestamp(),
-                     EntryPoint());
+  jsobj.AddFixedServiceId("code/%" Px64"-%" Px "",
+                          compile_timestamp(),
+                          EntryPoint());
   const String& user_name = String::Handle(PrettyName());
   const String& vm_name = String::Handle(Name());
   AddNameProperties(&jsobj, user_name, vm_name);
@@ -12626,7 +12707,7 @@
     JSONObject desc(&jsobj, "_descriptors");
     descriptors.PrintToJSONObject(&desc, false);
   }
-  const Array& inlined_function_table = Array::Handle(inlined_id_to_function());
+  const Array& inlined_function_table = Array::Handle(GetInlinedIdToFunction());
   if (!inlined_function_table.IsNull() &&
       (inlined_function_table.Length() > 0)) {
     JSONArray inlined_functions(&jsobj, "_inlinedFunctions");
@@ -12637,7 +12718,7 @@
       inlined_functions.AddValue(function);
     }
   }
-  const Array& intervals = Array::Handle(inlined_intervals());
+  const Array& intervals = Array::Handle(GetInlinedIntervals());
   if (!intervals.IsNull() && (intervals.Length() > 0)) {
     Smi& start = Smi::Handle();
     Smi& end = Smi::Handle();
@@ -12717,7 +12798,7 @@
 
 intptr_t Code::GetCallerId(intptr_t inlined_id) const {
   if (inlined_id < 0) return -1;
-  const Array& intervals = Array::Handle(inlined_intervals());
+  const Array& intervals = Array::Handle(GetInlinedIntervals());
   if (intervals.IsNull() || (intervals.Length() == 0)) return -1;
   Smi& temp_smi = Smi::Handle();
   for (intptr_t i = 0; i < intervals.Length() - Code::kInlIntNumEntries;
@@ -12735,7 +12816,7 @@
 void Code::GetInlinedFunctionsAt(
     intptr_t offset, GrowableArray<Function*>* fs) const {
   fs->Clear();
-  const Array& intervals = Array::Handle(inlined_intervals());
+  const Array& intervals = Array::Handle(GetInlinedIntervals());
   if (intervals.IsNull() || (intervals.Length() == 0)) {
     // E.g., for code stubs.
     return;
@@ -12758,7 +12839,7 @@
   }
 
   // Find all functions.
-  const Array& id_map = Array::Handle(inlined_id_to_function());
+  const Array& id_map = Array::Handle(GetInlinedIdToFunction());
   Smi& temp_smi = Smi::Handle();
   temp_smi ^= intervals.At(found_interval_ix + Code::kInlIntInliningId);
   intptr_t inlining_id = temp_smi.Value();
@@ -12777,7 +12858,7 @@
 
 void Code::DumpInlinedIntervals() const {
   OS::Print("Inlined intervals:\n");
-  const Array& intervals = Array::Handle(inlined_intervals());
+  const Array& intervals = Array::Handle(GetInlinedIntervals());
   if (intervals.IsNull() || (intervals.Length() == 0)) return;
   Smi& start = Smi::Handle();
   Smi& inlining_id = Smi::Handle();
@@ -12792,7 +12873,7 @@
         start.Value(), inlining_id.Value(), caller_id.Value());
   }
   OS::Print("Inlined ids:\n");
-  const Array& id_map = Array::Handle(inlined_id_to_function());
+  const Array& id_map = Array::Handle(GetInlinedIdToFunction());
   Function& function = Function::Handle();
   for (intptr_t i = 0; i < id_map.Length(); i++) {
     function ^= id_map.At(i);
@@ -12880,7 +12961,7 @@
   // TODO(turnidge): Should the user level type for Context be Context
   // or Object?
   AddTypeProperties(&jsobj, "Context", JSONType(), ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
 
   jsobj.AddProperty("length", num_variables());
 
@@ -13299,7 +13380,6 @@
 void ApiError::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "Error", JSONType(), ref);
-  jsobj.AddProperty("id", "");
   jsobj.AddProperty("message", ToErrorCString());
 }
 
@@ -13437,7 +13517,6 @@
 void LanguageError::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "Error", JSONType(), ref);
-  jsobj.AddProperty("id", "");
   jsobj.AddProperty("message", ToErrorCString());
 }
 
@@ -13529,7 +13608,6 @@
                                        bool ref) const {
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "Error", JSONType(), ref);
-  jsobj.AddProperty("id", "");
   jsobj.AddProperty("message", ToErrorCString());
 
   Instance& instance = Instance::Handle();
@@ -13574,7 +13652,6 @@
 void UnwindError::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "Error", JSONType(), ref);
-  jsobj.AddProperty("id", "");
   jsobj.AddProperty("message", ToErrorCString());
 }
 
@@ -14070,24 +14147,22 @@
   // Handle certain special instance values.
   if (raw() == Object::sentinel().raw()) {
     jsobj.AddProperty("type", "Sentinel");
-    jsobj.AddProperty("id", "objects/not-initialized");
+    jsobj.AddFixedServiceId("objects/not-initialized");
     jsobj.AddProperty("valueAsString", "<not initialized>");
     return;
   } else if (raw() == Object::transition_sentinel().raw()) {
     jsobj.AddProperty("type", "Sentinel");
-    jsobj.AddProperty("id", "objects/being-initialized");
+    jsobj.AddFixedServiceId("objects/being-initialized");
     jsobj.AddProperty("valueAsString", "<being initialized>");
     return;
   }
 
   AddTypeProperties(&jsobj, "Instance", JSONType(), ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   if (IsClosure()) {
-    const Function& closureFunc = Function::Handle(Closure::function(*this));
-    jsobj.AddProperty("closureFunc", closureFunc);
-    const Context& closureCtxt = Context::Handle(Closure::context(*this));
-    jsobj.AddProperty("closureCtxt", closureCtxt);
+    jsobj.AddProperty("function", Function::Handle(Closure::function(*this)));
+    jsobj.AddProperty("context", Context::Handle(Closure::context(*this)));
   }
   if (ref) {
     return;
@@ -15187,10 +15262,10 @@
     intptr_t id = type_cls.FindCanonicalTypeIndex(*this);
     ASSERT(id >= 0);
     intptr_t cid = type_cls.id();
-    jsobj.AddPropertyF("id", "classes/%" Pd "/types/%" Pd "", cid, id);
+    jsobj.AddFixedServiceId("classes/%" Pd "/types/%" Pd "", cid, id);
     jsobj.AddProperty("typeClass", type_cls);
   } else {
-    jsobj.AddServiceId("id", *this);
+    jsobj.AddServiceId(*this);
   }
   const String& user_name = String::Handle(PrettyName());
   const String& vm_name = String::Handle(Name());
@@ -15373,7 +15448,7 @@
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "TypeRef", JSONType(), ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   const String& user_name = String::Handle(PrettyName());
   const String& vm_name = String::Handle(Name());
   AddNameProperties(&jsobj, user_name, vm_name);
@@ -15607,7 +15682,7 @@
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "TypeParameter", JSONType(), ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   const String& user_name = String::Handle(PrettyName());
   const String& vm_name = String::Handle(Name());
   AddNameProperties(&jsobj, user_name, vm_name);
@@ -15823,7 +15898,7 @@
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "BoundedType", JSONType(), ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   const String& user_name = String::Handle(PrettyName());
   const String& vm_name = String::Handle(Name());
   AddNameProperties(&jsobj, user_name, vm_name);
@@ -15926,7 +16001,7 @@
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "int", JSONType(), ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   jsobj.AddProperty("valueAsString", ToCString());
 }
 
@@ -16355,7 +16430,7 @@
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "int", JSONType(), ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddPropertyF("id", "objects/int-%" Pd "", Value());
+  jsobj.AddFixedServiceId("objects/int-%" Pd "", Value());
   jsobj.AddPropertyF("valueAsString", "%" Pd "", Value());
 }
 
@@ -16619,7 +16694,7 @@
   // "Double".  Return "double" instead.
   AddTypeProperties(&jsobj, "double", "double", ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   jsobj.AddProperty("valueAsString", ToCString());
 }
 
@@ -17240,11 +17315,7 @@
   const intptr_t kMaxUsed =
       kIntptrMax / kBitsPerDigit / kLog2Dividend * kLog2Divisor;
   if (used > kMaxUsed) {
-    // Throw out of memory exception.
-    Isolate* isolate = Isolate::Current();
-    const Instance& exception =
-        Instance::Handle(isolate->object_store()->out_of_memory());
-    Exceptions::Throw(isolate, exception);
+    Exceptions::ThrowOOM();
     UNREACHABLE();
   }
   const int64_t bit_len = used * kBitsPerDigit;
@@ -17322,11 +17393,7 @@
   const int kHexDigitsPerDigit = 8;
   const intptr_t kMaxUsed = (kIntptrMax - 4) / kHexDigitsPerDigit;
   if (used > kMaxUsed) {
-    // Throw out of memory exception.
-    Isolate* isolate = Isolate::Current();
-    const Instance& exception =
-        Instance::Handle(isolate->object_store()->out_of_memory());
-    Exceptions::Throw(isolate, exception);
+    Exceptions::ThrowOOM();
     UNREACHABLE();
   }
   intptr_t hex_len = (used - 1) * kHexDigitsPerDigit;
@@ -18099,10 +18166,7 @@
     str ^= strings.At(i);
     const intptr_t str_len = str.Length();
     if ((kMaxElements - result_len) < str_len) {
-      Isolate* isolate = Isolate::Current();
-      const Instance& exception =
-          Instance::Handle(isolate->object_store()->out_of_memory());
-      Exceptions::Throw(isolate, exception);
+      Exceptions::ThrowOOM();
       UNREACHABLE();
     }
     result_len += str_len;
@@ -18204,13 +18268,13 @@
     // special string in their program.  Fixing this involves updating
     // the debugging api a bit.
     jsobj.AddProperty("type", "Sentinel");
-    jsobj.AddProperty("id", "objects/optimized-out");
+    jsobj.AddFixedServiceId("objects/optimized-out");
     jsobj.AddProperty("valueAsString", "<optimized out>");
     return;
   }
   AddTypeProperties(&jsobj, "String", JSONType(), ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   if (ref) {
     bool did_truncate = jsobj.AddPropertyStr("valueAsString", *this, 128);
     if (did_truncate) {
@@ -19121,7 +19185,7 @@
   // "Bool".  Return "bool" instead.
   AddTypeProperties(&jsobj, "bool", "bool", ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddPropertyF("id", "objects/bool-%s", str);
+  jsobj.AddFixedServiceId("objects/bool-%s", str);
   jsobj.AddPropertyF("valueAsString", "%s", str);
 }
 
@@ -19233,7 +19297,7 @@
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "List", JSONType(), ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   jsobj.AddProperty("length", Length());
   if (ref) {
     return;
@@ -19366,12 +19430,7 @@
     // TODO(Issue 2500): Need a better growth strategy.
     intptr_t new_capacity = (Capacity() == 0) ? 4 : Capacity() * 2;
     if (new_capacity <= Capacity()) {
-      // Use the preallocated out of memory exception to avoid calling
-      // into dart code or allocating any code.
-      Isolate* isolate = Isolate::Current();
-      const Instance& exception =
-          Instance::Handle(isolate->object_store()->out_of_memory());
-      Exceptions::Throw(isolate, exception);
+      Exceptions::ThrowOOM();
       UNREACHABLE();
     }
     Grow(new_capacity, space);
@@ -19484,7 +19543,7 @@
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "List", JSONType(), ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   jsobj.AddProperty("length", Length());
   if (ref) {
     return;
@@ -20532,7 +20591,7 @@
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "Instance", JSONType(), ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
   if (ref) {
     return;
   }
@@ -20603,7 +20662,7 @@
   JSONObject jsobj(stream);
   AddTypeProperties(&jsobj, "Instance", JSONType(), ref);
   PrintSharedInstanceJSON(&jsobj, ref);
-  jsobj.AddServiceId("id", *this);
+  jsobj.AddServiceId(*this);
 
   if (ref) {
     return;
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 5bc4ab1..3e0a630 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3579,24 +3579,15 @@
     V(BinaryMintOp)                                                            \
     V(DoubleToSmi)                                                             \
     V(Unknown)                                                                 \
-    V(InstanceGetter)                                                          \
     V(PolymorphicInstanceCallTestFail)                                         \
-    V(InstanceCallNoICData)                                                    \
-    V(IntegerToDouble)                                                         \
     V(UnaryMintOp)                                                             \
     V(BinaryDoubleOp)                                                          \
-    V(InstanceSetter)                                                          \
-    V(Equality)                                                                \
-    V(RelationalOp)                                                            \
-    V(EqualityClassCheck)                                                      \
-    V(NoTypeFeedback)                                                          \
     V(UnaryOp)                                                                 \
     V(UnboxInteger)                                                            \
     V(CheckClass)                                                              \
     V(CheckSmi)                                                                \
     V(CheckArrayBound)                                                         \
     V(AtCall)                                                                  \
-    V(Int32Load)                                                               \
     V(Uint32Load)                                                              \
     V(GuardField)                                                              \
     V(TestCids)                                                                \
@@ -3715,6 +3706,8 @@
   RawICData* AsUnaryClassChecks() const {
     return AsUnaryClassChecksForArgNr(0);
   }
+  RawICData* AsUnaryClassChecksForCid(
+      intptr_t cid, const Function& target) const;
 
   // Consider only used entries.
   bool AllTargetsHaveSameOwner(intptr_t owner_cid) const;
@@ -3727,6 +3720,7 @@
                         const Array& arguments_descriptor,
                         intptr_t deopt_id,
                         intptr_t num_args_tested);
+  static RawICData* NewFrom(const ICData& from, intptr_t num_args_tested);
 
   static intptr_t TestEntryLengthFor(intptr_t num_args);
 
@@ -3983,6 +3977,14 @@
   const Comments& comments() const;
   void set_comments(const Comments& comments) const;
 
+  RawObject* return_address_metadata() const {
+    return raw_ptr()->return_address_metadata_;
+  }
+  // Sets |return_address_metadata|.
+  void SetPrologueOffset(intptr_t offset) const;
+  // Returns -1 if no prologue offset is available.
+  intptr_t GetPrologueOffset() const;
+
   enum InlinedIntervalEntries {
     kInlIntStart = 0,
     kInlIntInliningId = 1,
@@ -3990,15 +3992,11 @@
     kInlIntNumEntries = 3,
   };
 
-  RawArray* inlined_intervals() const {
-    return raw_ptr()->inlined_intervals_;
-  }
-  void set_inlined_intervals(const Array& value) const;
+  RawArray* GetInlinedIntervals() const;
+  void SetInlinedIntervals(const Array& value) const;
 
-  RawArray* inlined_id_to_function() const {
-    return raw_ptr()->inlined_id_to_function_;
-  }
-  void set_inlined_id_to_function(const Array& value) const;
+  RawArray* GetInlinedIdToFunction() const;
+  void SetInlinedIdToFunction(const Array& value) const;
 
   void GetInlinedFunctionsAt(
       intptr_t offset, GrowableArray<Function*>* fs) const;
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index 7ad50ed..773839d 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -446,10 +446,11 @@
 };
 
 
-void ObjectGraph::Serialize(WriteStream* stream) {
+intptr_t ObjectGraph::Serialize(WriteStream* stream) {
   // Current encoding assumes objects do not move, so promote everything to old.
   isolate()->heap()->new_space()->Evacuate();
   WriteGraphVisitor visitor(isolate(), stream);
+  stream->WriteUnsigned(kObjectAlignment);
   stream->WriteUnsigned(0);
   stream->WriteUnsigned(0);
   stream->WriteUnsigned(0);
@@ -459,6 +460,7 @@
   }
   stream->WriteUnsigned(0);
   IterateObjects(&visitor);
+  return visitor.count() + 1;  // + root
 }
 
 }  // namespace dart
diff --git a/runtime/vm/object_graph.h b/runtime/vm/object_graph.h
index a5748b3..3163597 100644
--- a/runtime/vm/object_graph.h
+++ b/runtime/vm/object_graph.h
@@ -90,8 +90,9 @@
   intptr_t InboundReferences(Object* obj, const Array& references);
 
   // Write the isolate's object graph to 'stream'. Smis and nulls are omitted.
+  // Returns the number of nodes in the stream, including the root.
   // TODO(koda): Document format; support streaming/chunking.
-  void Serialize(WriteStream* stream);
+  intptr_t Serialize(WriteStream* stream);
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectGraph);
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 5e72ebf..7e678a6 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -4182,7 +4182,7 @@
   EXPECT(func_b.CanBeInlined());
 
   // After setting a breakpoint in a function A.b, it is no longer inlineable.
-  SourceBreakpoint* bpt =
+  Breakpoint* bpt =
       Isolate::Current()->debugger()->SetBreakpointAtLine(name,
                                                           kBreakpointLine);
   ASSERT(bpt != NULL);
@@ -4314,7 +4314,7 @@
     cls.PrintJSON(&js, true);
     elideSubstring("classes", js.ToCString(), buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Class\",\"id\":\"\",\"name\":\"bool\"}",
+        "{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"bool\"}",
         buffer);
   }
   // Function reference
@@ -4327,8 +4327,10 @@
     func.PrintJSON(&js, true);
     elideSubstring("classes", js.ToCString(), buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Function\",\"id\":\"\",\"name\":\"toString\","
-        "\"owner\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"bool\"},"
+        "{\"type\":\"@Function\",\"fixedId\":true,"
+        "\"id\":\"\",\"name\":\"toString\","
+        "\"owner\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"bool\"},"
         "\"kind\":\"RegularFunction\"}",
         buffer);
   }
@@ -4339,8 +4341,8 @@
     lib.PrintJSON(&js, true);
     elideSubstring("libraries", js.ToCString(), buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Library\",\"id\":\"\",\"name\":\"dart.core\","
-        "\"url\":\"dart:core\"}",
+        "{\"type\":\"@Library\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"dart.core\",\"uri\":\"dart:core\"}",
         buffer);
   }
   // Bool reference
@@ -4350,7 +4352,8 @@
     elideSubstring("classes", js.ToCString(), buffer);
     EXPECT_STREQ(
         "{\"type\":\"@bool\","
-        "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"bool\"},"
+        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"bool\"},\"fixedId\":true,"
         "\"id\":\"objects\\/bool-true\",\"valueAsString\":\"true\"}",
         buffer);
   }
@@ -4363,8 +4366,9 @@
     elideSubstring("_Smi@", buffer, buffer);
     EXPECT_STREQ(
         "{\"type\":\"@int\",\"_vmType\":\"@Smi\","
-        "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_Smi\","
-        "\"_vmName\":\"\"},"
+        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"_Smi\","
+        "\"_vmName\":\"\"},\"fixedId\":true,"
         "\"id\":\"objects\\/int-7\",\"valueAsString\":\"7\"}",
         buffer);
   }
@@ -4378,8 +4382,8 @@
     elideSubstring("_Mint@", buffer, buffer);
     EXPECT_STREQ(
         "{\"type\":\"@int\",\"_vmType\":\"@Mint\","
-        "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_Mint\","
-        "\"_vmName\":\"\"},"
+        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"_Mint\",\"_vmName\":\"\"},"
         "\"id\":\"\",\"valueAsString\":\"-9223372036854775808\"}",
         buffer);
   }
@@ -4395,8 +4399,8 @@
     elideSubstring("_Bigint@", buffer, buffer);
     EXPECT_STREQ(
         "{\"type\":\"@int\",\"_vmType\":\"@Bigint\","
-        "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_Bigint\","
-        "\"_vmName\":\"\"},"
+        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"_Bigint\",\"_vmName\":\"\"},"
         "\"id\":\"\",\"valueAsString\":\"44444444444444444444444444444444\"}",
         buffer);
   }
@@ -4410,8 +4414,8 @@
     elideSubstring("_Double@", buffer, buffer);
     EXPECT_STREQ(
         "{\"type\":\"@double\","
-        "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_Double\","
-        "\"_vmName\":\"\"},"
+        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"_Double\",\"_vmName\":\"\"},"
         "\"id\":\"\",\"valueAsString\":\"0.1234\"}",
         buffer);
   }
@@ -4425,7 +4429,7 @@
     elideSubstring("_OneByteString@", buffer, buffer);
     EXPECT_STREQ(
         "{\"type\":\"@String\","
-        "\"class\":{\"type\":\"@Class\",\"id\":\"\","
+        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_OneByteString\",\"_vmName\":\"\"},"
         "\"id\":\"\",\"valueAsString\":\"dw\"}",
         buffer);
@@ -4440,8 +4444,8 @@
     elideSubstring("_List@", buffer, buffer);
     EXPECT_STREQ(
         "{\"type\":\"@List\",\"_vmType\":\"@Array\","
-        "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_List\","
-        "\"_vmName\":\"\"},"
+        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"_List\",\"_vmName\":\"\"},"
         "\"id\":\"\",\"length\":0}",
         buffer);
   }
@@ -4456,7 +4460,8 @@
     elideSubstring("_GrowableList@", buffer, buffer);
     EXPECT_STREQ(
         "{\"type\":\"@List\",\"_vmType\":\"@GrowableObjectArray\","
-        "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_GrowableList\","
+        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"_GrowableList\","
         "\"_vmName\":\"\"},\"id\":\"\",\"length\":0}",
         buffer);
   }
@@ -4470,7 +4475,7 @@
     elideSubstring("_InternalLinkedHashMap@", buffer, buffer);
     EXPECT_STREQ(
         "{\"type\":\"@Instance\",\"_vmType\":\"@LinkedHashMap\","
-        "\"class\":{\"type\":\"@Class\",\"id\":\"\","
+        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_InternalLinkedHashMap\",\"_vmName\":\"\"},\"id\":\"\"}",
         buffer);
   }
@@ -4484,8 +4489,8 @@
     elideSubstring("_UserTag@", buffer, buffer);
     EXPECT_STREQ(
         "{\"type\":\"@Instance\",\"_vmType\":\"@UserTag\","
-        "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_UserTag\","
-        "\"_vmName\":\"\"},"
+        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"_UserTag\",\"_vmName\":\"\"},"
         "\"id\":\"\"}",
         buffer);
   }
@@ -4500,10 +4505,10 @@
     elideSubstring("_Type@", buffer, buffer);
     EXPECT_STREQ(
         "{\"type\":\"@Type\","
-        "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_Type\","
-        "\"_vmName\":\"\"},\"id\":\"\","
-        "\"typeClass\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"bool\"},"
-        "\"name\":\"bool\"}",
+        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"_Type\",\"_vmName\":\"\"},\"fixedId\":true,\"id\":\"\","
+        "\"typeClass\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"bool\"},\"name\":\"bool\"}",
         buffer);
   }
   // Null reference
@@ -4511,7 +4516,8 @@
     JSONStream js;
     Object::null_object().PrintJSON(&js, true);
     EXPECT_STREQ(
-        "{\"type\":\"@null\",\"id\":\"objects\\/null\","
+        "{\"type\":\"@null\",\"fixedId\":true,"
+        "\"id\":\"objects\\/null\","
         "\"valueAsString\":\"null\"}",
         js.ToCString());
   }
@@ -4520,7 +4526,8 @@
     JSONStream js;
     Object::sentinel().PrintJSON(&js, true);
     EXPECT_STREQ(
-        "{\"type\":\"Sentinel\",\"id\":\"objects\\/not-initialized\","
+        "{\"type\":\"Sentinel\",\"fixedId\":true,"
+        "\"id\":\"objects\\/not-initialized\","
         "\"valueAsString\":\"<not initialized>\"}",
         js.ToCString());
   }
@@ -4529,7 +4536,8 @@
     JSONStream js;
     Object::transition_sentinel().PrintJSON(&js, true);
     EXPECT_STREQ(
-        "{\"type\":\"Sentinel\",\"id\":\"objects\\/being-initialized\","
+        "{\"type\":\"Sentinel\",\"fixedId\":true,"
+        "\"id\":\"objects\\/being-initialized\","
         "\"valueAsString\":\"<being initialized>\"}",
         js.ToCString());
   }
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 1397869..810554a 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -635,7 +635,6 @@
   ASSERT(isolate != NULL);
   JSONObject space(object, "old");
   space.AddProperty("type", "HeapSpace");
-  space.AddProperty("id", "heaps/old");
   space.AddProperty("name", "old");
   space.AddProperty("vmName", "PageSpace");
   space.AddProperty("collections", collections());
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 3dc9370..0b82d60 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -40,6 +40,8 @@
 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements.");
 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\".");
 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks.");
+DEFINE_FLAG(bool, load_deferred_eagerly, false,
+    "Load deferred libraries eagerly.");
 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef.");
 DECLARE_FLAG(bool, error_on_bad_type);
@@ -5779,7 +5781,8 @@
   // If loading hasn't been requested yet, and if this is not a deferred
   // library import, call the library tag handler to request loading
   // the library.
-  if (library.LoadNotStarted() && !is_deferred_import) {
+  if (library.LoadNotStarted() &&
+      (!is_deferred_import || FLAG_load_deferred_eagerly)) {
     library.SetLoadRequested();
     CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url);
   }
@@ -5970,7 +5973,9 @@
       }
     }
   }
-  if ((top_level.fields.Length() > 0) || (top_level.functions.Length() > 0)) {
+
+  if ((library_.num_anonymous_classes() == 0) ||
+    (top_level.fields.Length() > 0) || (top_level.functions.Length() > 0)) {
     toplevel_class.AddFields(top_level.fields);
 
     const Array& array = Array::Handle(Z,
@@ -9265,7 +9270,7 @@
         LocalVariable* async_saved_try_ctx =
             LookupAsyncSavedTryContextVar(scope->parent(),
                                           try_block->try_index());
-        current_block_->statements->Add(
+        async_code->Add(
             new (Z) StoreLocalNode(
                 Scanner::kNoSourcePos,
                 saved_try_ctx,
diff --git a/runtime/vm/parser_test.cc b/runtime/vm/parser_test.cc
index c65cbca..e7450b7 100644
--- a/runtime/vm/parser_test.cc
+++ b/runtime/vm/parser_test.cc
@@ -363,7 +363,7 @@
   EXPECT_STREQ(
       // bb captures only value2 from aa.  No others.
       "a.b.aa.bb\n"
-      " 0 ContextVar    level=0   begin=32  end=42  name=value2\n"
+      " 0 ContextVar    level=0   begin=33  end=43  name=value2\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
 
@@ -379,9 +379,9 @@
       "a.b.aa\n"
       " 0 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
-      " 1 ContextLevel  level=1   scope=2   begin=22  end=50\n"
-      " 2 ContextVar    level=1   begin=28  end=50  name=value2\n"
-      " 3 StackVar      scope=2   begin=30  end=50  name=bb\n"
+      " 1 ContextLevel  level=1   scope=2   begin=22  end=52\n"
+      " 2 ContextVar    level=1   begin=28  end=52  name=value2\n"
+      " 3 StackVar      scope=2   begin=30  end=52  name=bb\n"
 
       // Closure call saves current context.
       "_FunctionImpl.call\n"
@@ -391,10 +391,10 @@
 
       // b captures value1 from a.
       "a.b\n"
-      " 0 ContextVar    level=0   begin=14  end=60  name=value1\n"
+      " 0 ContextVar    level=0   begin=14  end=62  name=value1\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
-      " 2 StackVar      scope=2   begin=18  end=60  name=aa\n"
+      " 2 StackVar      scope=2   begin=18  end=62  name=aa\n"
 
       // Closure call saves current context.
       "_FunctionImpl.call\n"
@@ -406,9 +406,9 @@
       "a\n"
       " 0 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
-      " 1 ContextLevel  level=1   scope=2   begin=4   end=68\n"
-      " 2 ContextVar    level=1   begin=10  end=68  name=value1\n"
-      " 3 StackVar      scope=2   begin=12  end=68  name=b\n",
+      " 1 ContextLevel  level=1   scope=2   begin=4   end=70\n"
+      " 2 ContextVar    level=1   begin=10  end=70  name=value1\n"
+      " 3 StackVar      scope=2   begin=12  end=70  name=b\n",
       CaptureVarsAtLine(lib, "a", 7));
 }
 
@@ -533,7 +533,7 @@
   EXPECT_VALID(lib);
   EXPECT_STREQ(
       "a.b.c\n"
-      " 0 ContextVar    level=0   begin=48  end=60  name=x\n"
+      " 0 ContextVar    level=0   begin=50  end=62  name=x\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
       "_FunctionImpl.call\n"
@@ -543,13 +543,13 @@
 
       // Doesn't save the entry context.  Chains to parent instead.
       "a.b\n"
-      " 0 ContextVar    level=0   begin=12  end=68  name=x\n"
+      " 0 ContextVar    level=0   begin=12  end=71  name=x\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
-      " 2 StackVar      scope=2   begin=46  end=68  name=c\n"
-      " 3 ContextLevel  level=1   scope=3   begin=18  end=46\n"
-      " 4 ContextVar    level=1   begin=22  end=46  name=i\n"
-      " 5 StackVar      scope=4   begin=32  end=46  name=d\n"
+      " 2 StackVar      scope=2   begin=47  end=71  name=c\n"
+      " 3 ContextLevel  level=1   scope=3   begin=18  end=47\n"
+      " 4 ContextVar    level=1   begin=22  end=47  name=i\n"
+      " 5 StackVar      scope=4   begin=32  end=47  name=d\n"
 
       "_FunctionImpl.call\n"
       " 0 StackVar      scope=1   begin=0   end=4   name=this\n"
@@ -559,9 +559,9 @@
       "a\n"
       " 0 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
-      " 1 ContextLevel  level=1   scope=2   begin=3   end=76\n"
-      " 2 ContextVar    level=1   begin=9   end=76  name=x\n"
-      " 3 StackVar      scope=2   begin=11  end=76  name=b\n",
+      " 1 ContextLevel  level=1   scope=2   begin=3   end=79\n"
+      " 2 ContextVar    level=1   begin=9   end=79  name=x\n"
+      " 3 StackVar      scope=2   begin=11  end=79  name=b\n",
       CaptureVarsAtLine(lib, "a", 10));
 }
 
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index c4e27e3..620d8c0 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -25,8 +25,11 @@
 namespace dart {
 
 
+DECLARE_FLAG(bool, trace_profiler);
+
 DEFINE_FLAG(bool, profile, true, "Enable Sampling Profiler");
 DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates.");
+
 #if defined(TARGET_OS_ANDROID) || defined(TARGET_ARCH_ARM64) ||                \
     defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
   DEFINE_FLAG(int, profile_period, 10000,
@@ -41,7 +44,7 @@
 DEFINE_FLAG(bool, profile_vm, true,
             "Always collect native stack traces.");
 #else
-DEFINE_FLAG(bool, profile_vm, true,
+DEFINE_FLAG(bool, profile_vm, false,
             "Always collect native stack traces.");
 #endif
 
@@ -240,6 +243,12 @@
   ASSERT(Sample::instance_size() > 0);
   samples_ = reinterpret_cast<Sample*>(
       calloc(capacity, Sample::instance_size()));
+  if (FLAG_trace_profiler) {
+    OS::Print("Profiler holds %" Pd " samples\n", capacity);
+    OS::Print("Profiler sample is %" Pd " bytes\n", Sample::instance_size());
+    OS::Print("Profiler memory usage = %" Pd " bytes\n",
+              capacity * Sample::instance_size());
+  }
   capacity_ = capacity;
   cursor_ = 0;
 }
@@ -262,7 +271,6 @@
   return At(cursor);
 }
 
-
 // Attempts to find the true return address when a Dart frame is being setup
 // or torn down.
 // NOTE: Architecture specific implementations below.
@@ -270,16 +278,11 @@
  public:
   ReturnAddressLocator(Sample* sample, const Code& code)
       : sample_(sample),
-        code_(Code::ZoneHandle(code.raw())),
-        is_optimized_(code.is_optimized()) {
+        code_(Code::ZoneHandle(code.raw())) {
     ASSERT(!code_.IsNull());
     ASSERT(code_.ContainsInstructionAt(pc()));
   }
 
-  bool is_code_optimized() {
-    return is_optimized_;
-  }
-
   uword pc() {
     return sample_->pc();
   }
@@ -288,12 +291,13 @@
   bool LocateReturnAddress(uword* return_address);
 
   // Returns offset into code object.
-  uword RelativePC() {
-    return pc() - code_.EntryPoint();
+  intptr_t RelativePC() {
+    ASSERT(pc() >= code_.EntryPoint());
+    return static_cast<intptr_t>(pc() - code_.EntryPoint());
   }
 
-  uint8_t* CodePointer(uword offset) {
-    const uword size = code_.Size();
+  uint8_t* CodePointer(intptr_t offset) {
+    const intptr_t size = code_.Size();
     ASSERT(offset < size);
     uint8_t* code_pointer = reinterpret_cast<uint8_t*>(code_.EntryPoint());
     code_pointer += offset;
@@ -309,152 +313,56 @@
  private:
   Sample* sample_;
   const Code& code_;
-  const bool is_optimized_;
 };
 
 
-#if defined(TARGET_ARCH_IA32)
+#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
 bool ReturnAddressLocator::LocateReturnAddress(uword* return_address) {
   ASSERT(return_address != NULL);
-  const uword offset = RelativePC();
-  const uword size = code_.Size();
-  if (is_optimized_) {
-    // 0: push ebp
-    // 1: mov ebp, esp
-    // 3: ...
-    if (offset == 0x0) {
-      // Stack layout:
-      // 0 RETURN ADDRESS.
-      *return_address = StackAt(0);
-      return true;
-    }
-    if (offset == 0x1) {
-      // Stack layout:
-      // 0 CALLER FRAME POINTER
-      // 1 RETURN ADDRESS
-      *return_address = StackAt(1);
-      return true;
-    }
-    ReturnPattern rp(pc());
-    if (rp.IsValid()) {
-      // Stack layout:
-      // 0 RETURN ADDRESS.
-      *return_address = StackAt(0);
-      return true;
-    }
-    return false;
-  } else {
-    // 0x00: mov edi, function
-    // 0x05: incl (inc usage count)   <-- this is optional.
-    // 0x08: cmpl (compare usage count)
-    // 0x0f: jump to optimize function
-    // 0x15: push ebp
-    // 0x16: mov ebp, esp
-    // 0x18: ...
-    ASSERT(size >= 0x08);
-    const uword incl_offset = 0x05;
-    const uword incl_length = 0x03;
-    const uint8_t incl_op_code = 0xFF;
-    const bool has_incl = (*CodePointer(incl_offset) == incl_op_code);
-    const uword push_fp_offset = has_incl ? 0x15 : 0x15 - incl_length;
-    if (offset <= push_fp_offset) {
-      // Stack layout:
-      // 0 RETURN ADDRESS.
-      *return_address = StackAt(0);
-      return true;
-    }
-    if (offset == (push_fp_offset + 1)) {
-      // Stack layout:
-      // 0 CALLER FRAME POINTER
-      // 1 RETURN ADDRESS
-      *return_address = StackAt(1);
-      return true;
-    }
-    ReturnPattern rp(pc());
-    if (rp.IsValid()) {
-      // Stack layout:
-      // 0 RETURN ADDRESS.
-      *return_address = StackAt(0);
-      return true;
-    }
-    return false;
+  const intptr_t offset = RelativePC();
+  ASSERT(offset >= 0);
+  const intptr_t size = code_.Size();
+  ASSERT(offset < size);
+  const intptr_t prologue_offset = code_.GetPrologueOffset();
+  if (offset < prologue_offset) {
+    // Before the prologue, return address is at the top of the stack.
+    // TODO(johnmccutchan): Some intrinsics and stubs do not conform to the
+    // expected stack layout. Use a more robust solution for those code objects.
+    *return_address = StackAt(0);
+    return true;
   }
-  UNREACHABLE();
-  return false;
-}
-#elif defined(TARGET_ARCH_X64)
-bool ReturnAddressLocator::LocateReturnAddress(uword* return_address) {
-  ASSERT(return_address != NULL);
-  const uword offset = RelativePC();
-  const uword size = code_.Size();
-  if (is_optimized_) {
-    // 0x00: leaq (load pc marker)
-    // 0x07: movq (load pool pointer)
-    // 0x0c: push rpb
-    // 0x0d: movq rbp, rsp
-    // 0x10: ...
-    const uword push_fp_offset = 0x0c;
-    if (offset <= push_fp_offset) {
-      // Stack layout:
-      // 0 RETURN ADDRESS.
-      *return_address = StackAt(0);
-      return true;
-    }
-    if (offset == (push_fp_offset + 1)) {
-      // Stack layout:
-      // 0 CALLER FRAME POINTER
-      // 1 RETURN ADDRESS
-      *return_address = StackAt(1);
-      return true;
-    }
-    ReturnPattern rp(pc());
-    if (rp.IsValid()) {
-      // Stack layout:
-      // 0 RETURN ADDRESS.
-      *return_address = StackAt(0);
-      return true;
-    }
-    return false;
-  } else {
-    // 0x00: leaq (load pc marker)
-    // 0x07: movq (load pool pointer)
-    // 0x0c: movq (load function)
-    // 0x13: incl (inc usage count)   <-- this is optional.
-    // 0x16: cmpl (compare usage count)
-    // 0x1d: jl + 0x
-    // 0x23: jmp [pool pointer]
-    // 0x27: push rbp
-    // 0x28: movq rbp, rsp
-    // 0x2b: ...
-    ASSERT(size >= 0x16);
-    const uword incl_offset = 0x13;
-    const uword incl_length = 0x03;
-    const uint8_t incl_op_code = 0xFF;
-    const bool has_incl = (*CodePointer(incl_offset) == incl_op_code);
-    const uword push_fp_offset = has_incl ? 0x27 : 0x27 - incl_length;
-    if (offset <= push_fp_offset) {
-      // Stack layout:
-      // 0 RETURN ADDRESS.
-      *return_address = StackAt(0);
-      return true;
-    }
-    if (offset == (push_fp_offset + 1)) {
-      // Stack layout:
-      // 0 CALLER FRAME POINTER
-      // 1 RETURN ADDRESS
-      *return_address = StackAt(1);
-      return true;
-    }
-    ReturnPattern rp(pc());
-    if (rp.IsValid()) {
-      // Stack layout:
-      // 0 RETURN ADDRESS.
-      *return_address = StackAt(0);
-      return true;
-    }
-    return false;
+  // Detect if we are:
+  // push ebp      <--- here
+  // mov ebp, esp
+  // on X64 the register names are different but the sequence is the same.
+  ProloguePattern pp(pc());
+  if (pp.IsValid()) {
+    // Stack layout:
+    // 0 RETURN ADDRESS.
+    *return_address = StackAt(0);
+    return true;
   }
-  UNREACHABLE();
+  // Detect if we are:
+  // push ebp
+  // mov ebp, esp  <--- here
+  // on X64 the register names are different but the sequence is the same.
+  SetFramePointerPattern sfpp(pc());
+  if (sfpp.IsValid()) {
+    // Stack layout:
+    // 0 CALLER FRAME POINTER
+    // 1 RETURN ADDRESS
+    *return_address = StackAt(1);
+    return true;
+  }
+  // Detect if we are:
+  // ret           <--- here
+  ReturnPattern rp(pc());
+  if (rp.IsValid()) {
+    // Stack layout:
+    // 0 RETURN ADDRESS.
+    *return_address = StackAt(0);
+    return true;
+  }
   return false;
 }
 #elif defined(TARGET_ARCH_ARM)
@@ -538,6 +446,11 @@
 
   if (!ral.LocateReturnAddress(&return_address)) {
     ASSERT(return_address == sample->pc_marker());
+    if (code.GetPrologueOffset() == 0) {
+      // Code has the prologue at offset 0. The frame is already setup and
+      // can be trusted.
+      return;
+    }
     // Could not find a better return address than the pc_marker.
     if (code.ContainsInstructionAt(return_address)) {
       // PC marker is in the same code as pc, no missing frame.
@@ -592,11 +505,11 @@
       : sample_(sample),
         frame_iterator_(isolate) {
     ASSERT(sample_ != NULL);
-    // Mark that this sample was collected from an exit frame.
-    sample_->set_exit_frame_sample(true);
   }
 
   void walk() {
+    // Mark that this sample was collected from an exit frame.
+    sample_->set_exit_frame_sample(true);
     intptr_t frame_index = 0;
     StackFrame* frame = frame_iterator_.NextFrame();
     while (frame != NULL) {
@@ -637,6 +550,7 @@
   }
 
   void walk() {
+    sample_->set_exit_frame_sample(false);
     if (!ValidFramePointer()) {
       sample_->set_ignore_sample(true);
       return;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 217f30f..a40c524 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -389,6 +389,9 @@
   bool IsFreeListElement() {
     return ((GetClassId() == kFreeListElement));
   }
+  bool IsScript() {
+    return ((GetClassId() == kScriptCid));
+  }
 
   intptr_t Size() const {
     uword tags = ptr()->tags_;
@@ -944,6 +947,12 @@
 
 
 class RawCode : public RawObject {
+  enum InlinedMetadataIndex {
+    kInlinedIntervalsIndex = 0,
+    kInlinedIdToFunctionIndex = 1,
+    kInlinedMetadataSize = 2,
+  };
+
   RAW_HEAP_OBJECT_IMPLEMENTATION(Code);
 
   RawObject** from() {
@@ -960,9 +969,11 @@
   RawArray* static_calls_target_table_;  // (code-offset, function, code).
   RawArray* stackmaps_;
   RawLocalVarDescriptors* var_descriptors_;
-  RawArray* inlined_intervals_;
-  RawArray* inlined_id_to_function_;
+  RawArray* inlined_metadata_;
   RawArray* comments_;
+  // If return_address_info_ is a Smi, it is the offset to the prologue.
+  // Else, return_address_info_ is null.
+  RawObject* return_address_metadata_;
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->comments_);
   }
@@ -985,9 +996,9 @@
   int32_t* data() { OPEN_ARRAY_START(int32_t, int32_t); }
   const int32_t* data() const { OPEN_ARRAY_START(int32_t, int32_t); }
 
-  friend class StackFrame;
-  friend class MarkingVisitor;
   friend class Function;
+  friend class MarkingVisitor;
+  friend class StackFrame;
 };
 
 
diff --git a/runtime/vm/regexp_assembler.h b/runtime/vm/regexp_assembler.h
index 56b4158..88aa06b 100644
--- a/runtime/vm/regexp_assembler.h
+++ b/runtime/vm/regexp_assembler.h
@@ -400,7 +400,7 @@
         case Token::kINDEX: return InstanceCallDescriptor(
                 Symbols::IndexToken(), token_kind, 2);
         case Token::kASSIGN_INDEX: return InstanceCallDescriptor(
-                Symbols::AssignIndexToken(), token_kind, 3);
+                Symbols::AssignIndexToken(), token_kind, 2);
         default:
           UNREACHABLE();
       }
diff --git a/runtime/vm/report_test.cc b/runtime/vm/report_test.cc
index b179055..4d99e01 100644
--- a/runtime/vm/report_test.cc
+++ b/runtime/vm/report_test.cc
@@ -29,10 +29,10 @@
                        js.ToCString());
       // Skip time.
       EXPECT_SUBSTRING("\"message\":{\"type\":\"JSCompatibilityWarning\","
-                       "\"script\":{\"type\":\"@Script\",\"id\":"
-                       "\"libraries\\/-1\\/scripts\\/Plug\","
-                       "\"name\":\"Plug\","
-                       "\"kind\":\"script\"},\"tokenPos\":0,"
+                       "\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
+                       "\"id\":\"libraries\\/-1\\/scripts\\/Plug\","
+                       "\"uri\":\"Plug\","
+                       "\"_kind\":\"script\"},\"tokenPos\":0,"
                        "\"message\":{\"type\":\"@String\"",
                        js.ToCString());
       // Skip private _OneByteString.
@@ -47,9 +47,10 @@
   }
   EXPECT_EQ(2, trace_buffer->Length());
   EXPECT_SUBSTRING("{\"type\":\"JSCompatibilityWarning\",\"script\":{\"type\":"
-                   "\"@Script\",\"id\":\"libraries\\/-1\\/scripts\\/Plug\","
-                   "\"name\":\"Plug\","
-                   "\"kind\":\"script\"},\"tokenPos\":0,"
+                   "\"@Script\",\"fixedId\":true,"
+                   "\"id\":\"libraries\\/-1\\/scripts\\/Plug\","
+                   "\"uri\":\"Plug\","
+                   "\"_kind\":\"script\"},\"tokenPos\":0,"
                    "\"message\":{\"type\":\"@String\"",
                    trace_buffer->At(0)->message);
   // Skip private _OneByteString.
@@ -57,9 +58,10 @@
                    trace_buffer->At(0)->message);
 
   EXPECT_SUBSTRING("{\"type\":\"JSCompatibilityWarning\",\"script\":{\"type\":"
-                   "\"@Script\",\"id\":\"libraries\\/-1\\/scripts\\/Plug\","
-                   "\"name\":\"Plug\","
-                   "\"kind\":\"script\"},\"tokenPos\":1,"
+                   "\"@Script\",\"fixedId\":true,"
+                   "\"id\":\"libraries\\/-1\\/scripts\\/Plug\","
+                   "\"uri\":\"Plug\","
+                   "\"_kind\":\"script\"},\"tokenPos\":1,"
                    "\"message\":{\"type\":\"@String\"",
                    trace_buffer->At(1)->message);
   // Skip private _OneByteString.
diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h
index f0580a6..27c9619 100644
--- a/runtime/vm/runtime_entry.h
+++ b/runtime/vm/runtime_entry.h
@@ -77,9 +77,9 @@
     ASSERT(arguments.ArgCount() == argument_count);                            \
     if (FLAG_trace_runtime_calls) OS::Print("Runtime call: %s\n", ""#name);    \
     {                                                                          \
-      Isolate* isolate = arguments.isolate();                                  \
-      Thread* thread = isolate->mutator_thread();                              \
+      Thread* thread = arguments.thread();                                     \
       ASSERT(thread == Thread::Current());                                     \
+      Isolate* isolate = thread->isolate();                                    \
       StackZone zone(isolate);                                                 \
       HANDLESCOPE(isolate);                                                    \
       DRT_Helper##name(isolate, thread, zone.GetZone(), arguments);            \
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index c41be4f..d0e6954 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -872,7 +872,6 @@
   ASSERT(isolate != NULL);
   JSONObject space(object, "new");
   space.AddProperty("type", "HeapSpace");
-  space.AddProperty("id", "heaps/new");
   space.AddProperty("name", "new");
   space.AddProperty("vmName", "Scavenger");
   space.AddProperty("collections", collections());
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 074c192..4acbb78 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -1196,7 +1196,7 @@
 }
 
 
-static SourceBreakpoint* LookupBreakpoint(Isolate* isolate, const char* id) {
+static Breakpoint* LookupBreakpoint(Isolate* isolate, const char* id) {
   size_t end_pos = strcspn(id, "/");
   if (end_pos == strlen(id)) {
     return NULL;
@@ -1204,7 +1204,7 @@
   const char* rest = id + end_pos + 1;  // +1 for '/'.
   if (strncmp("breakpoints", id, end_pos) == 0) {
     intptr_t bpt_id = 0;
-    SourceBreakpoint* bpt = NULL;
+    Breakpoint* bpt = NULL;
     if (GetIntegerId(rest, &bpt_id)) {
       bpt = isolate->debugger()->GetBreakpointById(bpt_id);
     }
@@ -1808,7 +1808,7 @@
   }
   const Script& script = Script::Cast(obj);
   const String& script_url = String::Handle(script.url());
-  SourceBreakpoint* bpt =
+  Breakpoint* bpt =
       isolate->debugger()->SetBreakpointAtLine(script_url, line);
   if (bpt == NULL) {
     js->PrintError(kNoBreakAtLine, NULL);
@@ -1834,8 +1834,34 @@
     return true;
   }
   const Function& function = Function::Cast(obj);
-  SourceBreakpoint* bpt =
-      isolate->debugger()->SetBreakpointAtEntry(function);
+  Breakpoint* bpt =
+      isolate->debugger()->SetBreakpointAtEntry(function, false);
+  if (bpt == NULL) {
+    js->PrintError(kNoBreakAtFunction, NULL);
+    return true;
+  }
+  bpt->PrintJSON(js);
+  return true;
+}
+
+
+static const MethodParameter* add_breakpoint_at_activation_params[] = {
+  ISOLATE_PARAMETER,
+  new IdParameter("objectId", true),
+  NULL,
+};
+
+
+static bool AddBreakpointAtActivation(Isolate* isolate, JSONStream* js) {
+  const char* object_id = js->LookupParam("objectId");
+  Object& obj = Object::Handle(LookupHeapObject(isolate, object_id, NULL));
+  if (obj.raw() == Object::sentinel().raw() || !obj.IsInstance()) {
+    PrintInvalidParamError(js, "objectId");
+    return true;
+  }
+  const Instance& closure = Instance::Cast(obj);
+  Breakpoint* bpt =
+      isolate->debugger()->SetBreakpointAtActivation(closure);
   if (bpt == NULL) {
     js->PrintError(kNoBreakAtFunction, NULL);
     return true;
@@ -1857,7 +1883,7 @@
     return true;
   }
   const char* bpt_id = js->LookupParam("breakpointId");
-  SourceBreakpoint* bpt = LookupBreakpoint(isolate, bpt_id);
+  Breakpoint* bpt = LookupBreakpoint(isolate, bpt_id);
   if (bpt == NULL) {
     fprintf(stderr, "ERROR1");
     PrintInvalidParamError(js, "breakpointId");
@@ -1874,7 +1900,7 @@
 
 static RawClass* GetMetricsClass(Isolate* isolate) {
   const Library& prof_lib =
-      Library::Handle(isolate, Library::ProfilerLibrary());
+      Library::Handle(isolate, Library::DeveloperLibrary());
   ASSERT(!prof_lib.IsNull());
   const String& metrics_cls_name =
       String::Handle(isolate, String::New("Metrics"));
@@ -2127,7 +2153,6 @@
 static bool GetTagProfile(Isolate* isolate, JSONStream* js) {
   JSONObject miniProfile(js);
   miniProfile.AddProperty("type", "TagProfile");
-  miniProfile.AddProperty("id", "profile/tag");
   isolate->vm_tag_counters()->PrintToJSONObject(&miniProfile);
   return true;
 }
@@ -2243,7 +2268,6 @@
   // TODO(koda): Provide some id that ties this request to async response(s).
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "OK");
-  jsobj.AddProperty("id", "ok");
   return true;
 }
 
@@ -2252,19 +2276,39 @@
   uint8_t* buffer = NULL;
   WriteStream stream(&buffer, &allocator, 1 * MB);
   ObjectGraph graph(isolate);
-  graph.Serialize(&stream);
-  JSONStream js;
-  {
-    JSONObject jsobj(&js);
+  intptr_t node_count = graph.Serialize(&stream);
+
+  // Chrome crashes receiving a single tens-of-megabytes blob, so send the
+  // snapshot in megabyte-sized chunks instead.
+  const intptr_t kChunkSize = 1 * MB;
+  intptr_t num_chunks =
+      (stream.bytes_written() + (kChunkSize - 1)) / kChunkSize;
+  for (intptr_t i = 0; i < num_chunks; i++) {
+    JSONStream js;
     {
-      JSONObject event(&jsobj, "event");
-      event.AddProperty("type", "ServiceEvent");
-      event.AddProperty("eventType", "_Graph");
-      event.AddProperty("isolate", isolate);
+      JSONObject jsobj(&js);
+      {
+        JSONObject event(&jsobj, "event");
+        event.AddProperty("type", "ServiceEvent");
+        event.AddProperty("eventType", "_Graph");
+        event.AddProperty("isolate", isolate);
+
+        event.AddProperty("chunkIndex", i);
+        event.AddProperty("chunkCount", num_chunks);
+        event.AddProperty("nodeCount", node_count);
+      }
+      jsobj.AddProperty("streamId", "_Graph");
     }
+
+    const String& message = String::Handle(String::New(js.ToCString()));
+
+    uint8_t* chunk_start = buffer + (i * kChunkSize);
+    intptr_t chunk_size = (i + 1 == num_chunks)
+        ? stream.bytes_written() - (i * kChunkSize)
+        : kChunkSize;
+
+    SendEvent(message, chunk_start, chunk_size);
   }
-  const String& message = String::Handle(String::New(js.ToCString()));
-  SendEvent(message, buffer, stream.bytes_written());
 }
 
 
@@ -2384,7 +2428,7 @@
   }
 
   // Handle non-heap objects.
-  SourceBreakpoint* bpt = LookupBreakpoint(isolate, id);
+  Breakpoint* bpt = LookupBreakpoint(isolate, id);
   if (bpt != NULL) {
     bpt->PrintJSON(js);
     return true;
@@ -2574,7 +2618,9 @@
     add_breakpoint_params },
   { "addBreakpointAtEntry", AddBreakpointAtEntry,
     add_breakpoint_at_entry_params },
-  { "clearCpuProfile", ClearCpuProfile,
+  { "_addBreakpointAtActivation", AddBreakpointAtActivation,
+    add_breakpoint_at_activation_params },
+  { "_clearCpuProfile", ClearCpuProfile,
     clear_cpu_profile_params },
   { "evaluate", Evaluate,
     evaluate_params },
@@ -2586,13 +2632,13 @@
     get_call_site_data_params },
   { "getClassList", GetClassList,
     get_class_list_params },
-  { "getCoverage", GetCoverage,
+  { "_getCoverage", GetCoverage,
     get_coverage_params },
-  { "getCpuProfile", GetCpuProfile,
+  { "_getCpuProfile", GetCpuProfile,
     get_cpu_profile_params },
   { "getFlagList", GetFlagList ,
     get_flag_list_params },
-  { "getHeapMap", GetHeapMap,
+  { "_getHeapMap", GetHeapMap,
     get_heap_map_params },
   { "_getInboundReferences", GetInboundReferences,
     get_inbound_references_params },
@@ -2600,13 +2646,13 @@
     get_instances_params },
   { "getIsolate", GetIsolate,
     get_isolate_params },
-  { "getIsolateMetric", GetIsolateMetric,
+  { "_getIsolateMetric", GetIsolateMetric,
     get_isolate_metric_params },
-  { "getIsolateMetricList", GetIsolateMetricList,
+  { "_getIsolateMetricList", GetIsolateMetricList,
     get_isolate_metric_list_params },
   { "getObject", GetObject,
     get_object_params },
-  { "getObjectByAddress", GetObjectByAddress,
+  { "_getObjectByAddress", GetObjectByAddress,
     get_object_by_address_params },
   { "_getRetainedSize", GetRetainedSize,
     get_retained_size_params },
@@ -2614,15 +2660,15 @@
     get_retaining_path_params },
   { "getStack", GetStack,
     get_stack_params },
-  { "getTagProfile", GetTagProfile,
+  { "_getTagProfile", GetTagProfile,
     get_tag_profile_params },
-  { "getTypeArgumentsList", GetTypeArgumentsList,
+  { "_getTypeArgumentsList", GetTypeArgumentsList,
     get_type_arguments_list_params },
   { "getVM", GetVM,
     get_vm_params },
-  { "getVMMetric", GetVMMetric,
+  { "_getVMMetric", GetVMMetric,
     get_vm_metric_params },
-  { "getVMMetricList", GetVMMetricList,
+  { "_getVMMetricList", GetVMMetricList,
     get_vm_metric_list_params },
   { "pause", Pause,
     pause_params },
@@ -2630,9 +2676,9 @@
     remove_breakpoint_params },
   { "resume", Resume,
     resume_params },
-  { "requestHeapSnapshot", RequestHeapSnapshot,
+  { "_requestHeapSnapshot", RequestHeapSnapshot,
     request_heap_snapshot_params },
-  { "setFlag", SetFlag,
+  { "_setFlag", SetFlag,
     set_flags_params },
   { "setName", SetName,
     set_name_params },
diff --git a/runtime/vm/service/protocol.md b/runtime/vm/service/protocol.md
deleted file mode 100644
index 71b2da1..0000000
--- a/runtime/vm/service/protocol.md
+++ /dev/null
@@ -1,542 +0,0 @@
-# Dart VM Service Protocol
-
-NOTE: The service api is still changing rapidly.  If you use the
-service api, expect to encounter non-compatible changes.
-
-Description
-How to start
-JSON
-Websocket
-
-## Types
-
-Every response returned by the VM Service has the <code>type</code>
-property.  This allows the client distinguish between different kinds
-of responses.  For example, global information about the VM is encoded
-in an response of type [VM](#VM) and information about an isolate is
-encoded in an response of type [Isolate](#Isolate).
-
-If the type name of a response begins with an <code>@</code> character
-then that response is a _reference_.  If the type name of a response
-does not begin with an <code>@</code> character then that response is
-an _object_ (or sometimes _full object_).  A reference is meant to be
-a subset of a full object with just enough information for the client
-to generate a reasonable-looking link.
-
-For example, an isolate reference may look like this...
-
-    {
-      type: "@Isolate",
-      id: "isolates/123",
-      name: "worker"
-    }
-
-... and a full isolate object would have additional properties:
-
-    {
-      type: "Isolate",
-      id: "isolates/123",
-      name: "worker"
-      entry: ...
-      heaps: ...
-      topFrame: ...
-      ...
-    }
-
-## Type Hierarchy
-
-The types returned by the VM Service fit into a type hierarchy, with a
-subtyping relationship as indicated by the following indented list:
-
-<pre>
-Object
-    ClassHeapStats
-    Class
-    Code
-    Context
-    Counter
-    Error
-    Field
-    FrameVar
-    Frame
-    Function
-    Gauge
-    Instance
-        AbstractType
-	    BoundedType
-	    TypeParameter
-	    TypeRef
-	    Type
-        List
-        Sentinel  // TODO - subtype of Instance or not?
-        String
-        bool
-        double
-        int
-        null
-    Isolate
-    Library
-    Location
-    Script
-    ServiceError
-    ServiceEvent
-    Socket
-    TypeArguments  // TODO - expose?
-    VM
-</pre>
-
-TODO: How to put links in a pre in markdown?
-
-A subtype is guaranteed to provide all of the properties of its
-parent type.  For example, an [int](#int) can be used as an
-[Instance](#Instance).
-
-The subtyping relationship also holds for reference types.  For
-example, [@int](#int) can be used as an [@Instance](#Instance).
-
-## IDs
-
-Most responses returned by the VM Service have an <code>id</code>
-property.  An id is used to request an object from the VM.  Each id is
-unique; that is to say, If two responses have the same id, they refer
-to the same object.  The converse is not true: the same object may
-occasionally be returned with two different ids.
-
-An id is either _global_ or _relative_.  Global ids can be requested
-from the VM directly by requesting the uri <code>/{global id}</code>.
-
-The following is a list of known,  fixed global ids:
-
-| id | uri | type
-| --- | --- | ---
-| vm | /vm | [VM](#VM)
-| flags | /flags | [FlagList](#FlagList)
-
-In addition, all isolates have global ids, but these ids are
-dynamically generated.  An isolate with an id like
-<code>isolates/123</code> would be available at the uri
-<code>/isolates/123</code>.
-
-Relative ids are used to refer to objects that are owned by an
-isolate.  Relative ids can be requested from the VM directly by
-requesting the uri <code>/{isolate&nbsp;id}/{relative&nbsp;id}</code>.
-
-For example, we can get information about a class with id
-<code>classes/Foo</code> from isolate <code>isolates/123</code> by
-requesting the uri <code>/isolates/123/classes/Foo</code> from the VM.
-
-The client must not parse ids -- they must be treated as opaque
-strings.  We reserve the right to change the ids of objects.
-
-## Names
-
-Many responses have the <code>name</code> property.  Names are
-provided so that objects can be displayed in a way that a Dart
-language programmer would find sensible.
-
-Note that names are not in any way unique.  Many objects will have the
-same name.
-
-## Private Properties
-
-Some properties returned by the VM Service begin with an underscore
-(<code>_</code>) character.  These properties are called _private
-properties_.  Private properties provide private information about the
-VM's implementation.  Private properties may be added, removed, or
-changed at any time with any release of the VM.  They are provided for
-those tools that need this level of internal access, such as the
-Observatory.
-
-For example, some responses will have the <code>_vmType</code>
-property.  This provides the VM-internal type name of an object, and
-is provided only when this type name differs from the
-<code>type</code> property.
-
-## Events
-
-TODO
-
-## Catalog of Types
-
-### <a name="AbstractType"></a>AbstractType
-
-### <a name="Breakpoint"></a>Breakpoint
-
-TODO: Get rid of Location or else use it more generally.
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "Breakpoint" |
-| id | String |
-| breakpointNumber | int |
-| enabled | bool |
-| resolved | bool |
-| location | [Location](#Location) |
-
-### <a name="Class"></a>Class
-
-Reference properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "@Class", "Class" |
-| id | String |
-| name | String |
-| _vmName? | String |
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| error? | [Error](#Error) | Error encountered during class finalization
-| implemented | bool |
-| abstract | bool |
-| patch | bool |
-| finalized | bool |
-| const | bool |
-| super? | [@Class](#Class) | Super class
-| library | [@Library](#Library) | Owning library
-| script? | [@Script](#Script) | Script containing class source
-| tokenPos? | int | starting token position of class source in script
-| endTokenPos? | int | end token position of class source in script
-| interfaces | List of [@Class](#Class) | interfaces this class has implemented
-| fields | List of [@Field](#Field) |
-| functions | List of [@Function](#Function) |
-| subclasses | List of [@Class](#Class) | classes which extend this class.
-| canonicalTypes | [@TypeList] | kill?
-| allocationStats | ClassHeapStats |
-
-### <a name="ClassHeapStats"></a>ClassHeapStats
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "ClassHeapStats" |
-| id | String |
-| class | [@Class](#Class) |
-| new | List of int | Allocation statistics for new space. See note below on allocation statistics list format.
-| old | List of int | Allocation statistics for old space. See note below on allocation statistics list format.
-| promotedInstances | int | number of instances promoted at last new-space GC.
-| promotedBytes | int | number of bytes promoted at last new-space GC.
-
-*Allocation statistics list format*
-
-| index | value | description
-| --- | --- | --- |
-| 0 | int | Instances allocated before last GC |
-| 1 | int | Bytes allocated before last GC |
-| 2 | int | Instances alive after last GC |
-| 3 | int | Bytes alive after last GC |
-| 4 | int | Instances allocated since last GC |
-| 5 | int | Bytes allocated since last GC |
-| 6 | int | Instances allocated since last accumulator reset |
-| 7 | int | Bytes allocated since last accumulator reset |
-
-### <a name="Code"></a>Code
-
-Reference properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "@Code", "Code"|
-| id | String |
-| name | String |
-| _vmName? | String |
-| start | String | starting address of code
-| end | String | ending address of code
-| isOptimized | bool |
-| isAlive | bool |
-| kind | String
-| function | [@Function](#Function) |
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| start | String | starting address of code
-| end | String | ending address of code
-| isOptimized | bool |
-| isAlive | bool |
-| kind | String
-| function | [@Function](#Function) |
-| object_pool | List of [@Object](#Object) |
-| disassembly | List of String | See note below on disassembly list format
-
-*Disassembly list format*
-
-| index | value | description
-| --- | --- | --- |
-| 0 | String | Address of instruction
-| 1 | String | Hex encoding of instruction
-| 2 | String | Human encoding of instruction
-| 0 + (3 * K) | String | Address of Kth instruction
-| 1 + (3 * K) | String | Hex encoding of instruction of Kth instruction
-| 2 + (3 * K) | String | Human encoding of instruction of Kth instruction
-
-### <a name="Error"></a>Error
-
-TODO: Drop id from Error.<br>
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "Error" |
-| _vmType? | String | VM internal name for this type.  Provided only when different from 'type'
-| id | String | always empty
-| kind | String |
-| message | String |
-
-### <a name="Field"></a>Field
-
-Reference properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "@Field", "Field" |
-| id | String |
-| name | String |
-| _vmName? | String |
-| value? | Instance | value associated with static field <-- do we want to include this in a field reference?
-| owner | [@Library](#Library),[@Class](#Class) | Owning library or class <-- handling of owner is inconsistent with Function
-| declared_type | [@AbstractType](#AbstractType) |
-| static | bool |
-| final | bool |
-| const | bool |
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| guard_nullable | bool | can this field hold a null?
-| guard_class | String OR [@Class](#Class) | "unknown", "dynamic", or a class
-| guard_length | String OR int | "unknown", "variable", or length of array
-| script? | [@Script](#Script) | Script containing field source
-| tokenPos? | int | starting token position of field source in script
-
-### <a name="Frame"></a>Frame
-
-TODO: Add type and id?<br>
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| script | [@Script](#Script) |
-| tokenPos | int |
-| function | [@Function](#Function) |
-| code | [@Code](#Code) |
-| vars | List of [FrameVar](#FrameVar) |
-
-### <a name="FrameVar"></a>FrameVar
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| name | String |
-| value | [@Instance](#Instance) |
-
-### <a name="Function"></a>Function
-
-Reference properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "@Function", "Function" |
-| id | String |
-| name | String |
-| _vmName? | String |
-| owningLibrary? | [@Library](#Library) | Set for non-top level functions
-| owningClass? | [@Class](#Class) | Set for non-top level functions
-| parent? | [@Function](#Function) | Parent function
-| kind | String |
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| static | bool | TODO: not consistent with Field 
-| const | bool |
-| optimizable | bool |
-| inlinable | bool |
-| usage_counter | int |
-| optimized_call_site_count | int |
-| deoptimizations | int |
-| script? | [@Script](#Script) | Script containing function source
-| tokenPos? | int | starting token position of function source in script
-| endTokenPos? | int | end token position of function source in script
-| unoptimized_code | [@Code](#Code) |
-| code | [@Code](#Code) | Current code
-
-### <a name="Isolate"></a>Isolate
-
-Reference properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "@Isolate", "Isolate" |
-| id | String |
-| mainPort | String | kill? |
-| name | String |
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| entry? | [@Function](#Function) |
-| heaps | ??? |
-| topFrame? | [Frame](#Frame) |
-| livePorts | int |
-| pauseOnExit | bool |
-| pauseEvent? | [DebuggerEvent](#DebuggerEvent) |
-| rootLib | [@Library](#Library) |
-| timers | ??? |
-| tagCounters | ??? |
-| error? | [Error](#Error) |
-| canonicalTypeArguments | | kill? |
-| libs | List of [@Library](#Library) |
-| features | List of String |
-
-### <a name="Library"></a>Library
-
-Reference properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "@Library", "Library" |
-| id | String |
-| name | String |
-| _vmName? | String | VM-internal name.  Provided only when different from 'name'.
-| url | String
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| classes | List of [@Class](#Class) |
-| imports | List of [@Library](#Library) |
-| variables | List of ... |
-| functions | List of [@Function](#Function) |
-| scripts | List of [@Script](#Script) |
-
-### <a name="Location"></a>Location
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "Location" |
-| script | [@Script](#Script) |
-| tokenPos | int |
-
-### <a name="null"></a>null
-
-Reference properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "@null", "null" |
-| id | String | |
-| valueAsString | String |
-
-Object properties:<br>
-
-TODO.
-
-### <a name="Object"></a>Object
-
-[Object](#Object) is the supertype of all responses returned by the VM
-Service.  It does not necessarily refer to an Object at the Dart
-language level (see [Instance](#Instance)).
-
-Reference properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "@Object", "Object" or subtype |
-| _vmType? | String | VM internal name for this type.  Provided only when different from 'type'
-| id | String |
-
-Object properties: none<br>
-
-### <a name="PcDescriptor"></a>PcDescriptor
-
-### <a name="Script"></a>Script
-
-Reference properties:
-
-| keys | values | comments | example |
-| --- | --- | ---
-| type | "@Script", "Script" |
-| id | String
-| name | String
-| _vmName? | String | VM-internal name.  Provided only when different from 'name'.
-| kind | String
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| owningLibrary | [@Library](#Library)
-| source | String
-| tokenPosTable | List of list of int. See note below about token line format.
-
-*Token line format*
-
-| index | value | comments
-| --- | --- | ---
-| 0   | int | line number
-| 1   | int | first token position
-| 2   | int | first column number
-| ... | ... | ...
-| 1 + (2 * k) | int | kth token position
-| 2 + (2 * k) | int | kth column number
-
-### <a name="Sentinel"></a>Sentinel
-
-TODO: Enumerate known Sentinels<br>
-TODO: Should this even have an id?  Maybe a *kind* instead.<br><br>
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "Sentinel" |
-| id | String | |
-| valueAsString | String |
-
-### <a name="ServiceEvent"></a>ServiceEvent
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "ServiceEvent" |
-| id | String | TODO: Remove |
-| eventType | String | "BreakpointReached", "BreakpointResolved", "ExceptionThrown", "IsolateCreated", "IsolateShutdown", "IsolateInterrupted" |
-| isolate | [@Isolate](#Isolate) |
-| breakpoint? | [Breakpoint](#Breakpoint) | for eventTypes "BreakpointResolved" and "BreakpointReached<br><br>TODO: Maybe make this @Breakpoint?
-| exception? | [@Instance](#Instance) | for eventType "ExceptionThrown"
-
-### <a name="VM"></a>VM
-
-Object properties:
-
-| keys | values | comments
-| --- | --- | ---
-| type | "VM" |
-| id | String |
-| targetCPU | String |
-| hostCPU | String |
-| date | String | kill? |
-| version | String |
-| pid | int |
-| assertsEnabled | bool | TODO: move to features? |
-| typeChecksEnabled | bool | TODO: move to features? |
-| uptime | double | seconds since vm started |
-| "isolates"    | List of [@Isolate](#Isolate)  |
-
diff --git a/runtime/vm/service/service.idl b/runtime/vm/service/service.idl
deleted file mode 100644
index ec83f21..0000000
--- a/runtime/vm/service/service.idl
+++ /dev/null
@@ -1,1140 +0,0 @@
-// <h2>Connecting to the VM Service</h2>
-//
-// TODO(turnidge): Describe how to connect, etc.
-//
-// <h2>Types</h2>
-//
-// Every non-error response returned by the VM Service has the
-// <code>type</code> property.  This allows the client distinguish
-// between different kinds of responses.
-//
-// If the type name of a response begins with an <code>@</code>
-// character then that response is a _reference_.  If the type name of
-// a response does not begin with an <code>@</code> character then
-// that response is an _object_ (or sometimes _full object_).  A
-// reference is meant to be a subset of a full object with just enough
-// information for the client to generate a reasonable-looking link.
-//
-// For example, an isolate reference may look like this...
-//
-//     {
-//       type: "@Isolate",
-//       id: "isolates/123",
-//       name: "worker"
-//     }
-//
-// ... and a full isolate object would have additional properties:
-//
-//     {
-//       type: "Isolate",
-//       id: "isolates/123",
-//       name: "worker"
-//       entry: ...
-//       heaps: ...
-//       topFrame: ...
-//       ...
-//     }
-//
-// <h2>IDs and Names</h2>
-//
-// Many responses returned by the VM Service have an <code>id</code>
-// property.  This is an identifier used to request an object from an
-// isolate using the <code>getObject</code> rpc.  If two responses
-// have the same id then they refer to the same object.  The converse
-// is not true: the same object may occasionally be returned with two
-// different ids.
-//
-// The client must not parse ids -- they must be treated as opaque
-// strings.  We reserve the right to change the ids of objects.
-//
-// TODO(turnidge): Describe id/handle expiration.  Provide guidance on
-// which responses are cacheable/constant.  Perhaps this needs to be
-// signaled in the Response itself.
-//
-// Many responses have the <code>name</code> property.  Names are
-// provided so that objects can be displayed in a way that a Dart
-// language programmer would find sensible.
-//
-// Note that names are not unique.  Many objects will have the same
-// name.
-//
-// <h2>Private Properties</h2>
-//
-// Some properties returned by the VM Service begin with an underscore
-// (&#95;) character.  These properties are called _private
-// properties_.  Private properties provide private information
-// specific to the VM's implementation.  Private properties may be
-// added, removed, or changed at any time with any release of the VM.
-// They are provided for those tools that need this level of internal
-// access, such as the Observatory.
-//
-// For example, some responses will have the <code>_vmType</code>
-// property.  This provides the VM-internal type name of an object,
-// and is provided only when this type name differs from the
-// <code>type</code> property.
-//
-// <b>If your application relies on private properties, you should expect
-// to update it when new versions of the VM are released.</b>
-//
-// <hr>
-
-interface Service {
-  // Returns global information about the Dart VM.
-  getVM() VM
-
-  // Changes the debugging name for some isolate.
-  setName(isolateId string, name string) Response
-
-  // Returns information about an isolate.
-  getIsolate(isolateId string) Isolate
-
-  // Returns a list of vm flags and their values.
-  getFlagList() FlagList
-
-  // Sets the value of a vm flag
-  setFlag(name string, value string) Response
-
-  // Loads an object by id from an isolate.
-  getObject(isolateId string, objectId string) Object
-
-  // The response is a subtype of Object or ObjectRef.
-  getObjectByAddress(address string, ref bool) Response
-
-  // Adds a breakpoint at the specified line.
-  //
-  // TODO(turnidge): Make line an int instead of a string.
-  addBreakpoint(isolateId string,
-                scriptId string,
-                line string) Breakpoint
-
-  // Adds a breakpoint at the entrypoint of the specified function.
-  addBreakpointAtEntry(isolateId string,
-                       functionId string) Breakpoint
-
-  // Removes the specified breakpoint
-  removeBreakpoint(isolateId string, breakpointId string) Response
-
-  // Requests that an isolate pause execution.
-  pause(isolateId string) Response
-
-  // Requests that an isolate resume execution.
-  //
-  // <code>step</code> is optional and indicates whether execution
-  // should single-step.
-  resume(isolateId string, step StepOption) Response
-
-  // Evaluate an expression in the context of some target.
-  eval(isolateId string, targetId string, expression string) InstanceRef
-
-  // Returns the current execution stack for an isolate.
-  //
-  // _full is an optional private parameter.
-  getStack(isolateId string, _full bool) Stack
-
-  // Returns code coverage information for a library, script, class,
-  // or function.
-  getCoverage(isolateId string, targetId string) CodeCoverage
-
-  // Returns call site cache information for a function.
-  _getCallSiteData(isolateId string, targetId string) _CallSiteData
-
-  // Returns a full cpu profile for an isolate.
-  //
-  // <code>tagSelector</code> is optional with default 'UserVM'.
-  getCpuProfile(isolateId string, tags TagSelector) CpuProfile
-
-
-  // Returns a simple tag-based profile for an isolate.
-  getTagProfile(isolateId string) TagProfile
-
-  // Returns an allocation profile for an isolate.
-  //
-  // <code>reset</code> is optional and indicates whether allocation
-  // accumulators should be reset.
-  //
-  // <code>gc</code> is optional and indicates whether a full
-  _getAllocationProfile(isolateId string,
-                        reset bool,
-                        gc GCOption) AllocationProfile
-
-  // Returns the heap map for an isolate.
-  getHeapMap(isolateId string) HeapMap
-
-  // Returns how many bytes are retained by some target Class or Instance.
-  _getRetainedSize(isolateId string, targetId string) InstanceRef
-
-  // Returns a path demonstrating why an object is retained in memory.
-  //
-  // TODO(turnidge): Make limit an int instead of a string.
-  _getRetainingPath(isolateId string,
-                    targetId string,
-                    limit int) RetainingPath
-
-  // Returns a collection of inbound references to some object.
-  //
-  // TODO(turnidge): Make limit an int instead of a string.
-  _getInboundReferences(isolateId string,
-                        targetId string,
-                        limit int) InboundReferences
-
-  _getInstances(isolateId string,
-                classId string,
-                limit int) InstanceSet
-
-  getClassList(isolateId string) ClassList
-
-  // When <code>onlyWithInstantiations</code> is true, the list only includes
-  // type arguments with instantiations. Otherwise, all type arguments are
-  // returned.
-  getTypeArgumentsList(isolateId string,
-                       onlyWithInstantiations bool) TypeArgumentsList
-
-  // Gets a list of isolate metrics.
-  getIsolateMetricList(isolateId string,
-                       type MetricSelector) MetricList
-
-  // Gets a specific isolate metric by id.
-  getIsolateMetric(isolateId string,
-                   metricId string) Metric
-
-  // Gets a list of vm metrics.
-  getVMMetricList() MetricList
-
-  // Gets a specific vm metric by id.
-  getVMMetric(metricId string) Metric
-
-  // A test rpc for vm requests.
-  _echoVM(text string) _EchoResponse
-
-  // A test rpc for isolate requests.
-  _echo(isolateId string,
-        text string) _EchoResponse
-
-  // Triggers a ServiceEvent with EventType '_Echo'.
-  _triggerEchoEvent(isolateId string,
-                    text string) _EchoResponse
-
-  // Response is bad JSON.
-  _respondWithMalformedJson(isolateId string) Response
-
-  // Response is not an object.
-  _respondWithMalformedObject(isolateId string) Response
-}
-
-
-// Every non-error top level response returned by the Service
-// interface extends <code>Response</code>.  This allows the client to
-// distinguish between different kinds of responses by using the
-// <code>type</code> property.
-struct Response {
-  // Every response returned by the VM Service has the
-  // <code>type</code> property.  This allows the client distinguish
-  // between different kinds of responses.
-  type    string
-
-  // Some responses will have the <code>_vmType</code> property.  This
-  // provides the VM-internal type name of an object, and is provided
-  // only when this type name differs from the <code>type</code>
-  // property.
-  _vmType string [optional]
-}
-
-
-// An asynchronous notification from the VM Service.
-struct ServiceEvent extends Response {
-  // What kind of event is this?
-  eventType ServiceEventType
-
-  // The isolate with which this event is associated.
-  isolate IsolateRef
-
-  // The breakpoint associated with this event, if applicable.
-  //
-  // This is provided for the events:
-  //   <code>PauseBreakpoint</code>
-  //   <code>BreakpointAdded</code>
-  //   <code>BreakpointRemoved</code>
-  //   <code>BreakpointResolved</code>
-  breakpoint Breakpoint [optional]
-
-  // The top stack frame associated with this event, if applicable.
-  //
-  // This is provided for the events:
-  //   <code>PauseBreakpoint</code>
-  //   <code>PauseInterrupted</code>
-  //   <code>PauseException</code>
-  //
-  // For the <code>Resume</code> event, the top frame is provided at
-  // all times except for the initial resume event that is delivered
-  // when an isolate begins execution.
-  topFrame Frame [optional]
-
-  // The exception associated with this event, if this is a
-  // <code>PauseException</code> event.
-  exception InstanceRef [optional]
-}
-
-
-// The type of a service event.
-enum ServiceEventType {
-  // Notification that a new isolate has started.
-  IsolateStart
-
-  // Notification that an isolate has exited.
-  IsolateExit
-
-  // Notification that isolate identifying information has changed.
-  // Currently used to notify of changes to the isolate debugging name
-  // via <code>setName</code>.
-  IsolateUpdate
-
-  // An isolate has paused at start, before executing code.
-  PauseStart
-
-  // An isolate has paused at exit, before terminating.
-  PauseExit
-
-  // An isolate has paused at a breakpoint or due to stepping.
-  PauseBreakpoint
-
-  // An isolate has paused due to interruption via <code>pause</code>.
-  PauseInterrupted
-
-  // An isolate has paused due to an exception.
-  //
-  // TODO(turnidge): Allow user to toggle pause-on-exceptions.
-  PauseException
-
-  // An isolate has started or resumed execution.
-  Resume
-
-  // A breakpoint has been added for an isolate.
-  BreakpointAdded
-
-  // An unresolved breakpoint has been resolved for an isolate.
-  BreakpointResolved
-
-  // A breakpoint has been removed.
-  BreakpointRemoved
-
-  // A garbage collection event.
-  GC
-
-  // The object graph is being delivered.  This is triggered via
-  // <code>requestHeapSnapshot</code>.
-  _Graph
-}
-
-
-struct VM extends Response {
-  // Word length on target architecture (e.g. 32, 64).
-  architectureBits int
-
-  // The CPU we are generating code for.
-  targetCPU string
-
-  // The CPU we are actually running on.
-  hostCPU string
-
-  // The Dart VM version string.
-  version string
-
-  // The process id for the VM.
-  pid string
-
-  // The time that the VM started in milliseconds since the epoch.
-  //
-  // Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
-  startTime int
-
-  // A list of isolates running in the VM.
-  isolates []IsolateRef
-
-  // Are assertions enabled in the VM?
-  //
-  // TODO(turnidge): Move to some sort of general settings list?
-  _assertsEnabled bool
-
-  // Are type checks enabled in the VM?
-  //
-  // TODO(turnidge): Move to some sort of general settings list?
-  _typeChecksEnabled bool
-}
-
-
-// A reference to an an isolate.
-struct IsolateRef extends Object {
-  // A numeric id for this isolate, represented as a string.  Unique.
-  number string
-
-  // A name identifying this isolate.  Not guaranteed to be unique.
-  name string
-}
-
-
-// An isolate running in the VM.
-struct Isolate {
-  // A numeric id for this isolate, represented as a string.  Unique.
-  number string
-
-  // A name identifying this isolate.  Not guaranteed to be unique.
-  name string
-
-  // The time that the VM started in milliseconds since the epoch.
-  //
-  // Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
-  startTime int
-
-  // The entry function for this isolate.
-  entry FunctionRef [optional]
-
-  // The number of live ports for this isolate.
-  livePorts int
-
-  // Will this isolate pause when exiting?
-  pauseOnExit bool
-
-  // The last pause event delivered to the isolate.  If the isolate is
-  // running, this will be a resume event.
-  pauseEvent ServiceEvent
-
-  // The error that is causing this isolate to exit, if applicable.
-  error Error [optional]
-
-  // The root library for this isolate.
-  rootLib LibraryRef
-
-  // A list of all libraries for this isolate.
-  libraries []LibraryRef
-
-  // A list of all breakpoints for this isolate.
-  breakpoints []Breakpoint
-
-  // A list of features enabled for this isolate.
-  features []string
-
-  // TODO
-  heaps int
-
-  // TODO
-  tagCounters int
-}
-
-
-// A list of flags.
-struct FlagList extends Response {
-  // A list of all flags which are set to default values.
-  unmodifiedFlags []Flag
-
-  // A list of all flags which have been modified by the user.
-  modifiedFlags []Flag
-}
-
-
-// A single flag.
-struct Flag {
-  // The name of the flag.
-  name string
-
-  // A description of the flag.
-  comment string
-
-  // The type of the flag.
-  flagType FlagType
-}
-
-
-// The type of a flag.
-enum FlagType {
-  bool
-  int
-  uint64_t
-  string
-}
-
-
-// A reference to a persistent object that lives in some isolate.
-struct ObjectRef extends Response {
-  // A unique identifier for an object.  Passed to
-  // <code>getObject</code> to load the full object.
-  id string
-}
-
-
-// A persistent object that lives in some isolate.
-struct Object extends Response {
-  // A unique identifier for this object.
-  id string
-}
-
-
-// TODO(turnidge): null type
-// TODO(turnidge): VMObject.
-
-
-// A reference to a Dart language library.
-struct LibraryRef extends ObjectRef {
-  // The name of this library.
-  name string
-
-  // The url of this library.
-  url string
-}
-
-
-// A Dart language library.
-struct Library extends Object {
-  // The name of this library.
-  name string
-
-  // The url of this library.
-  url string
-
-  // A list of the imports for this library.
-  imports []LibraryRef
-
-  // A list of the scripts which constitute this library.
-  scripts []ScriptRef
-
-  // A list of the top-level variables in this library.
-  variables []FieldRef
-
-  // A list of the top-level functions in this library.
-  functions []FunctionRef
-
-  // A list of all classes in this library.
-  classes []ClassRef
-}
-
-
-// A reference to a Dart language script.
-struct ScriptRef extends ObjectRef {
-  // A name for this script.
-  name string
-
-  // What kind of script is this?
-  kind ScriptKind
-}
-
-
-// A  Dart language script.
-struct Script extends Object {
-  // A name for this script.
-  name string
-
-  // What kind of script is this?
-  kind ScriptKind
-
-  // The library which owns this script.
-  library LibraryRef
-
-  // The source code for this script.  For certain built-in scripts,
-  // this may be reconstructed without source comments.
-  source string
-
-  // A table encoding a mapping from token position to line and column.
-  //
-  // Each entry in the array consists of a line number followed by
-  // (tokenPos, columnNumber) pairs:
-  //
-  //    [lineNumber, (tokenPos, columnNumber)*]
-  //
-  // For example, the following table:
-  //
-  //    [[1, 100, 5, 101, 8],[2, 102, 7]]
-  //
-  // Encodes the following mapping:
-  //
-  //    tokenPos  line   column
-  //    --------  ------ ------
-  //    100       1      5
-  //    101       1      8
-  //    102       2      7
-  //
-  // TODO(turnidge): The tool I'm using does not support [][].
-  // tokenPosTable [][]int
-  tokenPosTable int
-}
-
-
-enum ScriptKind {
-  script
-  library
-  source
-  patch
-}
-
-
-// A reference to a Dart language class.
-struct ClassRef extends ObjectRef {
-  // The name of this class.
-  name string
-
-  // A vm internal name, provided only when it is different than name.
-  _vmName string [optional]
-}
-
-
-// A Dart language class.
-struct Class extends Object {
-  // The name of this class.
-  name string
-
-  // A vm internal name, provided only when it is different than name.
-  _vmName string [optional]
-
-  // The error which occurred during class finalization, if it exists.
-  error InstanceRef [optional]
-
-  // Is this an abstract class?
-  abstract bool
-
-  // Is this a const class?
-  const bool
-
-  // Has this class been finalized?
-  finalized bool
-
-  // Is this class implemented?
-  implemented bool
-
-  // Is this a vm patch class?
-  patch bool
-
-  // The library which contains this class.
-  library LibraryRef
-
-  // The script which defines this class.  May be missing for some
-  // classes.
-  script ScriptRef
-
-  // The superclass of this class, if any.
-  super ClassRef [optional]
-
-  // A list of interface types for this class.
-  interfaces []TypeRef
-
-  // A list of fields in this class.  Does not include fields from
-  // superclasses.
-  fields []FieldRef
-
-  // A list of functions in this class.  Does not include functions
-  // from superclasses.
-  functions []FunctionRef
-
-  // A list of subclasses of this class.
-  subclasses []ClassRef
-
-  // Allocation statistics for this class, if available.
-  allocationStats ClassHeapStats [optional]
-}
-
-
-struct ClassHeapStats extends Response {
-  TODO int
-}
-
-
-// A reference to a Dart language field or variable.
-struct FieldRef extends ObjectRef {
-  // The name of this field.
-  name string
-
-  // A vm internal name, provided only when it is different than name.
-  _vmName string [optional]
-
-  // The value of this field, if the field is static.
-  value InstanceRef [optional]
-
-  // The owner of this field, which can be either a LibraryRef for a
-  // ClassRef.
-  owner ObjectRef
-
-  // The declared type of this field.
-  declaredType TypeRef
-
-  // Is this field const?
-  const bool
-
-  // Is this field final?
-  final bool
-
-  // Is this field static?
-  static bool
-}
-
-
-// A Dart language field or variable.
-struct Field extends ObjectRef {
-  // The name of this field.
-  name string
-
-  // A vm internal name, provided only when it is different than name.
-  _vmName string [optional]
-
-  // The value of this field, if the field is static.
-  value InstanceRef [optional]
-
-  // The owner of this field, which can be either a LibraryRef for a
-  // ClassRef.
-  owner ObjectRef
-
-  // The declared type of this field.
-  declaredType TypeRef
-
-  // Is this field const?
-  const bool
-
-  // Is this field final?
-  final bool
-
-  // Is this field static?
-  static bool
-
-  // The script containing this feild.
-  script ScriptRef [optional]
-
-  // The token position of this field.
-  tokenPos int [optional]
-
-  // Have we seen null assigned to this field?
-  _guardNullable bool
-
-  // Have we seen a single class assigned to this field?
-  //
-  // TODO(johnmccutchan): This can actually be a string 'unknown' or
-  // 'dynamic' or a ClassRef.  Change how this is encoded.
-  _guardClass string
-
-  // Have we seen a fixed length list assigned to this field?
-  //
-  // TODO(johnmccutchan): This can actually be a string 'unknown' or
-  // 'dynamic' or a ClassRef.  Change how this is encoded.
-  _guardLength string
-}
-
-
-// A reference to a Dart language function.
-struct FunctionRef extends ObjectRef {
-  // The name of this function.
-  name string
-
-  // A vm internal name, provided only when it is different than name.
-  _vmName string [optional]
-
-  // The owner of this field, which can be a LibraryRef, ClassRef, or
-  // a FunctionRef.
-  owner ObjectRef
-
-  // What kind of function is this?
-  kind FunctionKind
-}
-
-
-// A Dart language function.
-struct Function extends ObjectRef {
-  // The name of this function.
-  name string
-
-  // A vm internal name, provided only when it is different than name.
-  _vmName string [optional]
-
-  // What kind of function is this?
-  kind FunctionKind
-
-  // The owner of this field, which can be a LibraryRef, ClassRef, or
-  // a FunctionRef.
-  owner ObjectRef
-
-  // Is this function static?
-  //
-  // TODO(turnidge): This is inconsistent with FieldRef.
-  static bool
-
-  // Is this function const?
-  const bool
-
-  // The script containing this function.
-  script ScriptRef [optional]
-
-  // The first token position of this function.
-  tokenPos int [optional]
-
-  // The last token position of this function.
-  endTokenPos int [optional]
-
-  // The compiled code associated with this function.
-  code CodeRef [optional]
-
-  // Are we able to generate optimized code for this function?
-  _optimizable bool
-
-  // Are we able to inline this function?
-  _inlinable bool
-
-  // The unoptimized version of this function, if retained.
-  _unoptimizedCode CodeRef [optional]
-
-  // An indicator of how actively this function is used.
-  _usageCounter int
-
-  // TODO(johnmccutchan): Document.
-  _optimizedCallSiteCount int
-
-  // How many times has this function been deoptimized?
-  _deoptimizations int
-}
-
-
-enum FunctionKind {
-  RegularFunction
-  ClosureFunction
-  GetterFunction
-  SetterFunction
-  Constructor
-  ImplicitGetter
-  ImplicitSetter
-  ImplicitStaticFinalGetter
-  IrregexpFunction
-  StaticInitializer
-  MethodExtractor
-  NoSuchMethodDispatcher
-  InvokeFieldDispatcher
-  Collected
-  Native
-  Stub
-  Tag
-}
-
-
-// A reference to a compiled code object in the Dart VM.
-struct CodeRef extends ObjectRef {
-  // A name for this code object
-  name string
-
-  // A vm internal name, provided only when it is different than name.
-  _vmName string [optional]
-
-  // What kind of code object is this?
-  kind CodeKind
-
-  // Was this code generated using the optimizing compiler?
-  _optimized bool
-}
-
-
-// A compiled code object in the Dart VM.
-struct Code extends Object {
-  // A name for this code object
-  name string
-
-  // A vm internal name, provided only when it is different than name.
-  _vmName string [optional]
-
-  // What kind of code object is this?
-  kind CodeKind
-
-  // Was this code generated using the optimizing compiler?
-  _optimized bool
-
-  // The function which corresponds to this compiled code.
-  function FunctionRef
-
-  // The start address of the generated code as a hex string.
-  _startAddress string
-
-  // The end address of the generated code as a hex string.
-  _endAddress string
-
-  // The object pool associated with this code object.
-  _objectPool UNDOCUMENTED [optional]
-
-  // The disassembly of this code object.
-  _disassembly UNDOCUMENTED [optional]
-
-  // The pc descriptor table for this code object.
-  _descriptors UNDOCUMENTED [optional]
-
-  // The inlined function table for this code object.
-  _inlinedFunctions UNDOCUMENTED [optional]
-
-  // Inline interval information for this code object.
-  _inlinedIntervals UNDOCUMENTED [optional]
-}
-
-
-enum CodeKind {
-  Dart
-  Native
-  Stub
-  Tag
-  Collected
-}
-
-
-// A reference to a type arguments vector.
-struct TypeArgumentsRef extends ObjectRef {
-  // A name for this type argument list.
-  name string
-
-  // A vm internal name, provided only when it is different than name.
-  _vmName string
-}
-
-
-// The type argument vector for some instantiated generic type.
-struct TypeArguments extends Object {
-  // A name for this type argument list.
-  name string
-
-  // A vm internal name, provided only when it is different than name.
-  _vmName string
-
-  // A list of types.
-  types []TypeRef
-}
-
-
-// Represents an error object inside the VM.
-struct Error extends Object {
-  // An error message
-  message string
-}
-
-
-// A <code>InstanceRef</code> encodes a reference to a
-// <code>Instance</code> object.
-struct InstanceRef extends ObjectRef {
-  TODO int
-}
-
-
-struct TypeRef extends InstanceRef {
-  TODO2 int
-}
-
-
-// An <code>Instance</code> represents a Dart-language object.
-struct Instance extends Object {
-  TODO int
-}
-
-
-// A <code>Breakpoint</code> describes a debugger breakpoint.
-struct Breakpoint extends Object {
-  breakpointNumber int
-  resolved         bool
-  location         Location
-}
-
-
-// A <code>Location</code> encodes a location withing a dart script.
-//
-// TODO(turnidge): Should this really be broken out as its own type?
-// If so, we should use it more consistently in the api.  For example,
-// in Frame.
-struct Location {
-  script   ScriptRef
-  tokenPos int
-}
-
-
-// A <code>Variable</code> represents one name/value pair from a frame.
-struct Variable {
-  name  string
-  value InstanceRef
-}
-
-
-// A <code>Frame</code> represents one frame from an isolate's stack.
-struct Frame {
-  script   ScriptRef
-  tokenPos int
-  function FunctionRef
-  code     CodeRef
-  vars     []Variable
-}
-
-
-// A <code>Stack</code> represents an isolate's execution stack.
-struct Stack extends Response {
-  frames []Frame
-}
-
-
-struct CodeCoverage extends Response {
-  TODO int
-}
-
-
-struct _CacheEntry {
-  receiverClass ClassRef
-  count         int
-}
-
-
-struct _CallSite {
-  name         string
-  line         int
-  column       int
-  cacheEntries []_CacheEntry
-}
-
-
-struct _CallSiteData extends Response {
-  function  FunctionRef
-  callSites []_CallSite
-}
-
-// A <code>TagProfile</code> is a limited profile encoded as parallel
-// arrays of tag names and tag values.
-struct TagProfile extends Response {
-  names    []string
-  counters []int
-}
-
-
-// An <code>AllocationProfile</code> encodes an allocation profile.
-struct AllocationProfile extends Response {
-  todo int
-}
-
-
-// A <code>CpuProfile</code> encodes a full cpu profile.
-struct CpuProfile extends Response {
-  samples        int
-  depth          int
-  period         int
-  timeSpan       float
-  exclusive_trie []int
-  codes          []CodeRegion
-}
-
-
-// A <code>CodeRegion</code> represents profiling information for a
-// specific <code>Code</code> object.
-struct CodeRegion {
-  kind            string
-  inclusive_ticks int
-  exclusive_ticks int
-  code            CodeRef
-  ticks           []int
-  callers         []int
-}
-
-// An <code>HeapMap</code> provides a memory view of all heap allocated objects.
-struct HeapMap extends Response {
-  todo int
-}
-
-
-// An <code>HeapMap</code> provides a memory view of all heap allocated objects.
-struct RetainingPath extends Response {
-  length int
-  elements []RetainingPathElement
-}
-
-
-// One entry in a <code>RetainingPath</code>.
-struct RetainingPathElement {
-  index           int
-  element         InstanceRef
-  parentListIndex int [optional]
-  parentField     FieldRef [optional]
-}
-
-
-struct InboundReferences extends Response {
-  length int
-  references []InboundReference
-}
-
-
-// TODO(koda): slot can actually be a string, and integer or a
-// FieldRef.  Fix this to be consistent with RetainingPathElement.
-struct InboundReference {
-  source InstanceRef
-  slot   int
-}
-
-
-struct InstanceSet {
-  placeholder int
-}
-
-
-struct ClassList extends Response {
-  classes []ClassRef
-}
-
-
-struct TypeArgumentsList extends Response {
-  tableSize int
-  tableUsed int
-  typeArguments []TypeArgumentsRef
-}
-
-
-struct MetricList extends Response {
-  metrics []Metric
-}
-
-
-struct Metric extends Response {
-  name string
-  description string
-}
-
-
-struct Gauge extends Metric {
-  value float
-  min float
-  max float
-}
-
-
-struct Counter extends Metric {
-  value float
-}
-
-
-// A <code>GCOption</code> is used to indicate which form of garbage
-// collection is requested.
-enum GCOption {
-  full
-}
-
-// A <code>StepOption</code> is used to indicate which form of
-// single-stepping is requested.
-enum StepOption {
-  into
-  over
-  out
-}
-
-// A <code>TagSelector</code> is used to indicate which sets of tags
-// should take precedence in a cpu profile.
-enum TagSelector {
-  UserVM
-  UserOnly
-  VMUser
-  VMOnly
-  None
-}
-
-// A <code>MetricSelector</code> is used to indicate which list of metrics
-// should be retrieved from an isolate.
-enum MetricSelector {
-  Dart
-  Native
-}
-
-
-struct _EchoResponse extends Response {
-  text string
-}
-
-
-struct UNDOCUMENTED {
-  TODO int
-}
\ No newline at end of file
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
new file mode 100644
index 0000000..93e1ed6
--- /dev/null
+++ b/runtime/vm/service/service.md
@@ -0,0 +1,1738 @@
+# Dart VM Service Protocol 0.0
+
+This document describes _version 0.0_ of the Dart VM Service Protocol.
+This protocol is used to communicate with a running Dart Virtual
+Machine.
+
+To use the Service Protocol, start the VM with the *--observe* flag.
+The VM will start a webserver which services protocol requests via WebSocket.
+It is possible to make HTTP (non-WebSocket) requests,
+but this does not allow access to VM _events_ and is not documented
+here.
+
+The Service Protocol is based on JSON-RPC 2.0
+(http://www.jsonrpc.org/specification).  The Service Protocol has been
+extended to support pushing _events_ to the client, which is
+apparently outside the scope of the JSON-RPC specification.
+
+**Table of Contents**
+
+- [RPCs, Requests, and Responses](#rpcs-requests-and-responses)
+- [Events](#events)
+- [Types](#types)
+- [IDs and Names](#ids-and-names)
+- [Versioning](#versioning)
+- [Private RPCs, Types, and Properties](#private-rpcs-types-and-properties)
+- [Public RPCs](#public-rpcs)
+	- [addBreakpoint](#addbreakpoint)
+	- [addBreakpointAtEntry](#addbreakpointatentry)
+	- [evaluate](#evaluate)
+	- [evaluateInFrame](#evaluateinframe)
+	- [getFlagList](#getflaglist)
+	- [getIsolate](#getisolate)
+	- [getObject](#getobject)
+	- [getStack](#getstack)
+	- [getVersion](#getversion)
+	- [getVM](#getvm)
+	- [pause](#pause)
+	- [removeBreakpoint](#removebreakpoint)
+	- [resume](#resume)
+	- [setName](#setname)
+	- [streamCancel](#streamcancel)
+	- [streamListen](#streamlisten)
+- [Public Types](#public-types)
+	- [Bool](#bool)
+	- [BoundField](#boundfield)
+	- [BoundVariable](#boundvariable)
+	- [Breakpoint](#breakpoint)
+	- [Class](#class)
+	- [ClassList](#classlist)
+	- [Code](#code)
+	- [CodeKind](#codekind)
+	- [Double](#double)
+	- [Error](#error)
+	- [Event](#event)
+	- [EventType](#eventtype)
+	- [Field](#field)
+	- [Flag](#flag)
+	- [FlagList](#flaglist)
+	- [FlagType](#flagtype)
+	- [Frame](#frame)
+	- [Function](#function)
+	- [FunctionKind](#functionkind)
+	- [Instance](#instance)
+	- [Int](#int)
+	- [Isolate](#isolate)
+	- [Library](#library)
+	- [List](#list)
+	- [ListElement](#listelement)
+	- [Message](#message)
+	- [Null](#null)
+	- [Object](#object)
+	- [Sentinel](#sentinel)
+	- [SentinelType](#sentineltype)
+	- [Script](#script)
+	- [ScriptKind](#scriptkind)
+	- [Stack](#stack)
+	- [StepOption](#stepoption)
+	- [String](#string)
+	- [Success](#success)
+	- [Type](#type)
+	- [TypeArguments](#typearguments)
+	- [Response](#response)
+	- [Version](#version)
+	- [VM](#vm)
+- [Revision History](#revision-history)
+
+## RPCs, Requests, and Responses
+
+An RPC request is a JSON object sent to the server.  Here is an
+example [getVersion](#getversion) request:
+
+```
+{
+  "jsonrpc": "2.0",
+  "method": "getVersion",
+  "params": {},
+  "id": "1"
+}
+```
+
+Currently the _id_ property must be a string.  The Service Protocol
+optionally accepts requests without the _jsonprc_ property.
+
+An RPC response is a JSON object (http://json.org/).  The response always specifies an
+_id_ property to pair it with the corresponding request.  If the RPC
+was successful, the _result_ property provides the result.
+
+Here is an example response for our [getVersion](#getversion) request above:
+
+```
+{
+  "json-rpc": "2.0",
+  "result": {
+    "type": "Version",
+    "major": 0,
+    "minor": 0
+  }
+  "id": "1"
+}
+```
+
+Parameters for RPC requests are always provided as _named_ parameters.
+The JSON-RPC spec provides for _positional_ parameters as well, but they
+are not supported by the Dart VM.
+
+By convention, every response returned by the Service Protocol is a subtype
+of [Response](#response) and provides a _type_ paramters which can be used
+to distinguish the exact return type.  In the example above, the
+[Version](#version) type is returned.
+
+Here is an example [streamListen](#streamlisten) request which provides
+a parameter:
+
+```
+{
+  "jsonrpc": "2.0",
+  "method": "streamListen",
+  "params": {
+    "streamId": "GC",
+  },
+  "id": "2"
+}
+```
+
+<a name="rpc-error"></a>
+When an RPC encounters an error, it is provided in the _error_
+property of the response object.  JSON-RPC errors always provide
+_code_, _message_, and _data_ properties.
+
+Here is an example error response for our [streamListen](#streamlisten)
+request above.  This error would be generated if we were attempting to
+subscribe to the _GC_ stream multiple times from the same client.
+
+```
+{
+  "json-rpc": "2.0",
+  "error": {
+    "code": 101,
+    "message": "Stream already subscribed",
+    "data": {
+      "details": "The stream 'GC' is already subscribed"
+    }
+  }
+  "id": "2"
+}
+```
+
+In addition the the [error codes](http://www.jsonrpc.org/specification#error_object)
+specified in the JSON-RPC spec, we use the following application specific error codes:
+
+code | message | meaning
+---- | ------- | -------
+100 | Invalid stream | An invalid _streamId_ parameter was provided
+101 | Stream already subscribed | The client is already subscribed to the specified _streamId_
+102 | Stream not subscribed | The client is not subscribed to the specified _streamId_
+200 | VM must be paused | This operation is only valid when the VM is paused
+201 | Cannot set breakpoint | The VM is unable to set a breakpoint at the specified line or function
+300 | Profiling is disabled | The operation is unable to complete because profiling is disabled
+
+## Events
+
+By using the [streamListen](#streamlisten) and [streamCancel](#streamcancel) RPCs, a client may
+request to be notified when an _event_ is posted to a specific
+_stream_ in the VM.  Every stream has an associated _stream id_ which
+is used to name that stream.
+
+Each stream provides access to certain kinds of events.  For example the _Isolate_ stream provides
+access to events pertaining to isolate births, deaths, and name changes.  See [streamListen](#streamlisten)
+for a list of the well-known stream ids and their associated events.
+
+Events arrive asynchronously over the WebSocket and always have the
+_streamId_ and _event_ properties:
+
+```
+{
+  "event": {
+    "type": "Event",
+    "eventType": "IsolateExit",
+    "isolate": {
+      "type": "@Isolate",
+      "id": "isolates/33",
+      "number": "51048743613",
+      "name": "worker-isolate"
+    }
+  }
+  "streamId": "Isolate"
+}
+```
+
+It is considered a _backwards compatible_ change to add a new type of event to an existing stream.
+Clients should be written to handle this gracefully.
+
+
+## Types
+
+By convention, every result and event provided by the Service Protocol
+is a subtype of [Response](#response) and has the _type_ property.
+This allows the client to distinguish different kinds of responses.  For example,
+information about a Dart function is returned using the [Function](#function) type.
+
+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
+intended to be a subset of an object which provides enough information
+to generate a reasonable looking reference to the object.
+
+For example, an [@Isolate](#isolate) reference has the _type_, _id_, _name_ and
+_number_ properties:
+
+```
+  "result": {
+    "type": "@Isolate",
+    "id": "isolates/33",
+    "number": "51048743613"
+    "name": "worker-isolate"
+  }
+```
+
+But an [Isolate](#isolate) object has more information:
+
+```
+  "result": {
+    "type": "Isolate",
+    "id": "isolates/33",
+    "number": "51048743613"
+    "name": "worker-isolate"
+    "rootLib": { ... }
+    "entry": ...
+    "heaps": ...
+     ...
+  }
+```
+
+## IDs and Names
+
+Many responses returned by the Service Protocol have an _id_ property.
+This is an identifier used to request an object from an isolate using
+the [getObject](#getobject) RPC.  If two responses have the same _id_ then they
+refer to the same object.  The converse is not true: the same object
+may sometimes be returned with two different values for _id_.
+
+The _id_ property should be treated as an opaque string by the client:
+it is not meant to be parsed.
+
+An id can be either _temporary_ or _fixed_:
+
+* A _temporary_ id can expire over time.  The VM allocates certain ids
+  in a ring which evicts old ids over time.
+
+* A _fixed_ id will never expire, but the object it refers to may
+  be collected.  The VM uses fixed ids for objects like scripts,
+  libraries, and classes.
+
+If an id is fixed, the _fixedId_ property will be true. If an id is temporary
+the _fixedId_ property will be omitted.
+
+Sometimes a temporary id may expire.  In this case, some RPCs may return
+an _Expired_ [Sentinel](#sentinel) to indicate this.
+
+The object referred to by an id may be collected by the VM's garbage
+collector.  In this case, some RPCs may return a _Collected_ [Sentinel](#sentinel)
+to indicate this.
+
+Many objects also have a _name_ property.  This is provided so that
+objects can be displayed in a way that a Dart language programmer
+would find familiar.  Names are not unique.
+
+## Versioning
+
+The [getVersion](#getversion) RPC can be used to find the version of the protocol
+returned by a VM.  The _Version_ response has a major and a minor
+version number:
+
+```
+  "result": {
+    "type": "Version",
+    "major": 0,
+    "minor": 0
+  }
+```
+
+The major version number is incremented when the protocol is changed
+in a potentially _incompatible_ way.  An example of an incompatible
+change is removing a non-optional property from a result.
+
+The minor version number is incremented when the protocol is changed
+in a _backwards compatible_ way.  An example of a backwards compatible
+change is adding a property to a result.
+
+## Private RPCs, Types, and Properties
+
+Any RPC, type, or property which begins with an underscore is said to
+be _private_.  These RPCs, types, and fields can be changed at any
+time without changing major or minor version numbers.
+
+The intention is that the Service Protocol will evolve by adding
+private RPCs which may, over time, migrate to the public api as they
+become stable.  Some private types and properties expose VM specific
+implementation state and will never be appropriate to add to
+the public api.
+
+## Public RPCs
+
+The following is a list of all public RPCs supported by the Service Protocol.
+
+An RPC is described using the following format:
+
+```
+ReturnType methodName(parameterType1 parameterName1,
+                      parameterType2, parameterName2,
+                      ...)
+```
+
+If an RPC says it returns type _T_ it may actually return _T_ or any
+[subtype](#public-types) of _T_.  For example, an
+RPC which is declared to return [@Instance](#instance) may actually
+return [@Int](#int).
+
+If an RPC can return one or more independent types, this is indicated
+with the vertical bar:
+
+```
+ReturnType1|ReturnType2
+```
+
+Any RPC may return an _error_ response as [described above](#rpc-error).
+
+Some parameters are optional.  This is indicated by the text
+_[optional]_ following the parameter name:
+
+```
+ReturnType methodName(parameterType parameterName [optional)
+```
+
+A description of the return types and parameter types is provided
+in the section on [public types](#public-types).
+
+### addBreakpoint
+
+```
+Breakpoint addBreakpoint(string isolateId,
+                         string scriptId,
+                         int line)
+```
+
+The _addBreakpoint_ RPC is used to add a breakpoint at a specific line
+of some script.
+
+If no breakpoint is possible at that line, the _201_ (Cannot set
+breakpoint) error code is returned.
+
+Note that breakpoints are added and removed on a per-isolate basis.
+
+See [Breakpoint](#breakpoint).
+
+### addBreakpointAtEntry
+
+```
+Breakpoint addBreakpointAtEntry(string isolateId,
+                                string functionId)
+```
+The _addBreakpointAtEntry_ RPC is used to add a breakpoint at the
+entrypoint of some function.
+
+If no breakpoint is possible at the function entry, the _201_ (Cannot set
+breakpoint) error code is returned.
+
+See [Breakpoint](#breakpoint).
+
+Note that breakpoints are added and removed on a per-isolate basis.
+
+### evaluate
+
+```
+@Instance|@Error|Sentinel evaluate(string isolateId,
+                                   string targetId,
+                                   string expression)
+```
+
+The _evaluate_ RPC is used to evaluate an expression in the context of
+some target.
+
+_targetId_ may refer to a [Library](#library), [Class](#class), or
+[Instance](#instance).
+
+If _targetId_ is a temporary id which has expired, then then _Expired_
+[Sentinel](#sentinel) is returned.
+
+If _targetId_ refers to an object which has been collected by the VM's
+garbage collector, then the _Collected_ [Sentinel](#sentinel) is
+returned.
+
+If an error occurs while evaluating the expression, an [@Error](#error)
+reference will be returned.
+
+If the expression is evaluated successfully, an [@Instance](#instance)
+reference will be returned.
+
+### evaluateInFrame
+
+```
+@Instance|@Error evaluateInFrame(string isolateId,
+                                 int frame,
+                                 string expression)
+```
+
+The _evaluateInFrame_ RPC is used to evaluate an expression in the context of
+a particular stack frame.  _frame_ is the index of the desired [Frame](#frame),
+with an index of _0_ indicating the top (most recent) frame.
+
+If an error occurs while evaluating the expression, an [@Error](#error)
+reference will be returned.
+
+If the expression is evaluated successfully, an [@Instance](#instance)
+reference will be returned.
+
+### getFlagList
+
+```
+FlagList getFlagList()
+```
+
+The _getFlagList RPC returns a list of all command line flags in the
+VM along with their current values.
+
+See [FlagList](#flaglist).
+
+### getIsolate
+
+```
+Isolate getIsolate(string isolateId)
+```
+
+The _getIsolate_ RPC is used to lookup an _Isolate_ object by its _id_.
+
+See [Isolate](#isolate).
+
+### getObject
+
+```
+Object|Sentinel  getObject(string isolateId,
+                           string objectId)
+```
+
+The _getObject_ RPC is used to lookup an _object_ from some isolate by
+its _id_.
+
+If _objectId_ is a temporary id which has expired, then then _Expired_
+[Sentinel](#sentinel) is returned.
+
+If _objectId_ refers to an object which has been collected by the VM's
+garbage collector, then the _Collected_ [Sentinel](#sentinel) is
+returned.
+
+If the object handle has not expired and the object has not been
+collected, then an [Object](#object) will be returned.
+
+### getStack
+
+```
+Stack getStack(string isolateId)
+```
+
+The _getStack_ RPC is used to retrieve the current execution stack and
+message queue for an isolate.  The isolate does not need to be paused.
+
+See [Stack](#stack).
+
+### getVersion
+
+```
+Version getVersion()
+```
+
+The _getVersion_ RPC is used to determine what version of the Service Protocol is served by a VM.
+
+See [Version](#version).
+
+### getVM
+
+```
+VM getVM()
+```
+
+The _getVM_ RPC returns global information about a Dart virtual machine.
+
+See [VM](#vm).
+
+### pause
+
+```
+Success pause(string isolateId)
+```
+
+The _pause_ RPC is used to interrupt a running isolate.  The RPC enqueues the interrupt request and potentially returns before the isolate is paused.
+
+When the isolate is paused an event will be sent on the _Debug_ stream.
+
+See [Success](#success).
+
+### removeBreakpoint
+
+```
+Success removeBreakpoint(string isolateId,
+                         string breakpointId)
+```
+
+The _removeBreakpoint_ RPC is used to remove a breakpoint by its _id_.
+
+Note that breakpoints are added and removed on a per-isolate basis.
+
+See [Success](#success).
+
+### resume
+
+```
+Success resume(string isolateId,
+               StepOption step [optional])
+```
+
+The _resume_ RPC is used to resume execution of a paused isolate.
+
+If the _step_ parameter is not provided, the program will resume
+regular execution.
+
+If the _step_ parameter is provided, it indicates what form of
+single-stepping to use.
+
+step | meaning
+---- | -------
+into | Single step, entering function calls
+over | Single step, skipping over function calls
+out | Single step until the current function exits
+
+See [Success](#success), [StepOption](#StepOption).
+
+### setName
+
+```
+Success setName(string isolateId,
+                string name)
+```
+
+The _setName_ RPC is used to change the debugging name for an isolate.
+
+See [Success](#success).
+
+### streamCancel
+
+```
+Success streamCancel(string streamId)
+```
+
+The _streamCancel_ RPC cancels a stream subscription in the VM.
+
+If the client is not subscribed to the stream, the _102_ (Stream not
+subscribed) error code is returned.
+
+See [Success](#success).
+
+### streamListen
+
+```
+Success streamListen(string streamId)
+```
+
+The _streamListen_ RPC subscribes to a stream in the VM.  Once
+subscribed, the client will begin receiving events from the stream.
+
+If the client is not subscribed to the stream, the _101_ (Stream already
+subscribed) error code is returned.
+
+The _streamId_ parameter may have the following published values:
+
+streamId | event types provided
+-------- | -----------
+Isolate | IsolateStart, IsolateExit, IsolateUpdate
+Debug | PauseStart, PauseExit, PauseBreakpoint, PauseInterrupted, PauseException, Resume, BreakpointAdded, BreakpointResolved, BreakpointRemoved, Inspect
+GC | GC
+
+It is considered a _backwards compatible_ change to add a new type of event to an existing stream.
+Clients should be written to handle this gracefully, perhaps by warning and ignoring.
+
+See [Success](#success).
+
+## Public Types
+
+The following is a list of all public types produced by the Service Protocol.
+
+We define a small set of primitive types, based on JSON equivalents.
+
+type | meaning
+---- | -------
+string | JSON string values
+bool | JSON _true_, _false_
+int | JSON numbers without fractions or exponents
+float | any JSON number
+
+Note that the Service Protocol does not use JSON _null_.
+
+We describe the format of our JSON objects with the following class format:
+
+```
+class T {
+  string name;
+  int count;
+  ...
+}
+```
+
+This describes a JSON object type _T_ with some set of expected properties.
+
+Types are organized into an inheritance hierarchy.  If type _T_
+extends type _S_...
+
+```
+class S {
+  string a;
+}
+
+class T extends S {
+  string b;
+}
+```
+
+...then that means that all properties of _S_ are also present in type
+_T_.  In the example above, type _T_ would have the expected
+properties _a_ and _b_.
+
+If a property has an _Array_ type, it is written with brackets:
+
+```
+  PropertyType[] arrayProperty;
+```
+
+If a property is optional, it is suffixed with the text _[optional]_:
+
+```
+  PropertyType optionalProperty [optional];
+```
+
+If a property can have multiple independent types, we denote this with
+a vertical bar:
+
+```
+  PropertyType1|PropertyType2 complexProperty;
+```
+
+When a string is only permitted to take one of a certain set of values,
+we indicate this by the use of the _enum_ format:
+
+```
+enum PermittedValues {
+  Value1,
+  Value2
+}
+```
+
+This means that _PermittedValues_ is a _string_ with two potential values,
+_Value1_ and _Value2_.
+
+### Bool
+
+```
+class @Bool extends @Instance {
+  // The value of this bool as a string, either 'true' or 'false'.
+  string valueAsString;
+}
+```
+
+_@Bool_ is a reference to a _Bool_.
+
+```
+class Bool extends Instance {
+  // The value of this bool as a string, either 'true' or 'false'.
+  string valueAsString;
+}
+```
+
+An _Bool_ represents an instance of the Dart language class _bool_.
+
+### BoundField
+
+```
+class BoundField {
+  @Field decl;
+  @Instance|Sentinel value;
+}
+```
+
+A _BoundField_ represents a field bound to a particular value in an
+_Instance_.
+
+If the field is uninitialized, the _value_ will be the
+_NotInitialized_ [Sentinel](#sentinel).
+
+If the field is being initialized, the _value_ will be the
+_BeingInitialized_ [Sentinel](#sentinel).
+
+### BoundVariable
+
+```
+class BoundVariable {
+  string name;
+  @Instance|Sentinel value;
+}
+```
+
+A _BoundVariable_ represents a local variable bound to a particular value
+in a _Frame_.
+
+If the variable is uninitialized, the _value_ will be the
+_NotInitialized_ [Sentinel](#sentinel).
+
+If the variable is being initialized, the _value_ will be the
+_BeingInitialized_ [Sentinel](#sentinel).
+
+If the variable has been optimized out by the compiler, the _value_
+will be the _OptimizedOut_ [Sentinel](#sentinel).
+
+### Breakpoint
+
+```
+class Breakpoint extends Response {
+  int breakpointNumber;
+  bool resolved;
+  @Script script;
+  int tokenPos;
+}
+```
+
+A _Breakpoint_ describes a debugger breakpoint.
+
+### Class
+
+```
+class @Class extends @Object {
+  // The name of this class.
+  string name;
+}
+```
+
+_@Class_ is a reference to a _Class_.
+
+```
+class Class extends Object {
+  // The name of this class.
+  string name;
+
+  // The error which occurred during class finalization, if it exists.
+  @Instance error [optional];
+
+  // Is this an abstract class?
+  bool abstract;
+
+  // Is this a const class?
+  bool const;
+
+  // Has this class been finalized?
+  bool finalized;
+
+  // Is this class implemented?
+  bool implemented;
+
+  // Is this a vm patch class?
+  bool patch;
+
+  // The library which contains this class.
+  @Library library;
+
+  // The script which defines this class.  May be missing for some
+  // classes.
+  @Script script;
+
+  // The superclass of this class, if any.
+  @Class super [optional];
+
+  // A list of interface types for this class.
+  @Type[] interfaces;
+
+  // A list of fields in this class.  Does not include fields from
+  // superclasses.
+  @Field[] fields;
+
+  // A list of functions in this class.  Does not include functions
+  // from superclasses.
+  @Function[] functions;
+
+  // A list of subclasses of this class.
+  @Class[] subclasses;
+}
+```
+
+A _Class_ provides information about a Dart language class.
+
+### ClassList
+
+```
+class ClassList extends Response {
+  @Class[] classes;
+}
+```
+
+### Code
+
+```
+class @Code extends @Object {
+  // A name for this code object.
+  string name;
+
+  // What kind of code object is this?
+  CodeKind kind;
+}
+```
+
+_@Code_ is a reference to a _Code_ object.
+
+```
+class @Code extends @Object {
+  // A name for this code object.
+  string name;
+
+  // What kind of code object is this?
+  CodeKind kind;
+}
+```
+
+A _Code_ object represents compiled code in the Dart VM.
+
+### CodeKind
+
+```
+enum CodeKind {
+  Dart,
+  Native,
+  Stub,
+  Tag,
+  Collected
+}
+```
+
+### Double
+
+```
+class @Double extends @Instance {
+  // The value of this double as a string.
+  //
+  // Suitable for passing to double.parse().
+  string valueAsString;
+}
+```
+
+_@Double_ is a reference to a _Double_.
+
+```
+class Double extends Instance {
+  // The value of this double as a string.
+  //
+  // Suitable for passing to double.parse().
+  string valueAsString;
+}
+```
+
+A _Double_ represents an instance of the Dart language class _double_.
+
+### Error
+
+```
+class @Error extends @Object {
+  // A description of the error.
+  string message;
+}
+```
+
+_@Error_ is a reference to an _Error_.
+
+```
+class Error extends Object {
+  // A description of the error.
+  string message;
+
+  // If this error is due to an unhandled exception, this
+  // is the exception thrown.
+  @Instance exception [optional];
+
+  // If this error is due to an unhandled exception, this
+  // is the stacktrace object.
+  @Instance stacktrace [optional];
+}
+```
+
+An _Error_ represents a Dart language level error.  This is distinct from an
+[rpc error](#rpc-error).
+
+An error may occur when:
+
+- The program has encountered an unhandled exception
+- The program has encountered a syntax error (or another Dart language error)
+- The program has encountered an unhandled erroneous condition in native code
+- The program has been terminated
+
+### Event
+
+```
+class Event extends Response {
+  // What kind of event is this?
+  EventType eventType;
+
+  // The isolate with which this event is associated.
+  @Isolate isolate;
+
+  // The breakpoint associated with this event, if applicable.
+  //
+  // This is provided for the events:
+  //   PauseBreakpoint
+  //   BreakpointAdded
+  //   BreakpointRemoved
+  //   BreakpointResolved
+  Breakpoint breakpoint [optional];
+
+  // The top stack frame associated with this event, if applicable.
+  //
+  // This is provided for the events:
+  //   PauseBreakpoint
+  //   PauseInterrupted
+  //   PauseException
+  //
+  // For the Resume event, the top frame is provided at
+  // all times except for the initial resume event that is delivered
+  // when an isolate begins execution.
+  Frame topFrame [optional];
+
+  // The exception associated with this event, if this is a
+  // PauseException event.
+  @Instance exception [optional];
+}
+```
+
+An _Event_ is an asynchronous notification from the VM.  It is delivered
+only when the client has subscribed to an event stream using the
+[streamListen](#streamListen) RPC.
+
+For more information, see [events](#events).
+
+### EventType
+
+```
+enum EventType {
+  // Notification that a new isolate has started.
+  IsolateStart,
+
+  // Notification that an isolate has exited.
+  IsolateExit,
+
+  // Notification that isolate identifying information has changed.
+  // Currently used to notify of changes to the isolate debugging name
+  // via <code>setName</code>.
+  IsolateUpdate,
+
+  // An isolate has paused at start, before executing code.
+  PauseStart,
+
+  // An isolate has paused at exit, before terminating.
+  PauseExit,
+
+  // An isolate has paused at a breakpoint or due to stepping.
+  PauseBreakpoint,
+
+  // An isolate has paused due to interruption via <code>pause</code>.
+  PauseInterrupted,
+
+  // An isolate has paused due to an exception.
+  PauseException,
+
+  // An isolate has started or resumed execution.
+  Resume,
+
+  // A breakpoint has been added for an isolate.
+  BreakpointAdded,
+
+  // An unresolved breakpoint has been resolved for an isolate.
+  BreakpointResolved,
+
+  // A breakpoint has been removed.
+  BreakpointRemoved,
+
+  // A garbage collection event.
+  GC
+}
+```
+
+### Field
+
+```
+class @Field extends @Object {
+  // The name of this field.
+  string name;
+
+  // The owner of this field, which can be either a Library or a
+  // Class.
+  @Object owner;
+
+  // The declared type of this field.
+  @Type declaredType;
+
+  // Is this field const?
+  bool const;
+
+  // Is this field final?
+  bool final;
+
+  // Is this field static?
+  bool static;
+
+  // The value of this field, if the field is static.
+  @Instance value [optional];
+}
+```
+
+An _@Field_ is a reference to a _Field_.
+
+```
+class Field extends Object {
+  // The name of this field.
+  string name;
+
+  // The owner of this field, which can be either a Library or a
+  // Class.
+  @Object owner;
+
+  // The declared type of this field.
+  @Type declaredType;
+
+  // Is this field const?
+  bool const;
+
+  // Is this field final?
+  bool final;
+
+  // Is this field static?
+  bool static;
+
+  // The value of this field, if the field is static.
+  @Instance value [optional];
+
+  // The script containing this feild.
+  @Script script [optional];
+
+  // The token position of this field.
+  int tokenPos [optional];
+}
+```
+
+A _Field_ provides information about a Dart language field or
+variable.
+
+
+### Flag
+
+```
+class Flag {
+  // The name of the flag.
+  string name;
+
+  // A description of the flag.
+  string comment;
+
+  // The type of the flag.
+  FlagType flagType;
+
+  // The value of this flag as a string.
+  //
+  // If this property is absent, then the value of the flag was NULL.
+  string valueAsString [optional];
+}
+```
+
+A _Flag_ represents a single VM command line flag.
+
+### FlagList
+
+```
+class FlagList extends Response {
+  // A list of all flags which are set to default values.
+  unmodifiedFlags []Flag
+
+  // A list of all flags which have been modified by the user.
+  modifiedFlags []Flag
+}
+```
+
+A _FlagList_ represents the complete set of VM command line flags.
+
+### FlagType
+
+```
+enum FlagType {
+  bool,
+  int,
+  uint64_t,
+  string
+}
+```
+
+A _FlagType_ indicates the type of a VM command line flag.
+
+### Frame
+
+```
+class Frame {
+  int index;
+  @Function function;
+  @Code code;
+  @Script script;
+  int tokenPos;
+  BoundVariable[] vars;
+}
+```
+
+### Function
+
+```
+class @Function extends @Object {
+  // The name of this function.
+  string name;
+
+  // The owner of this field, which can be a Library, Class, or a
+  // Function.
+  @Library|@Class|@Function owner;
+
+  // What kind of function is this?
+  FunctionKind kind;
+}
+```
+
+An _@Function_ is a reference to a _Function_.
+
+
+```
+// A Dart language function.
+class Function extends Object {
+  // The name of this function.
+  string name;
+
+  // The owner of this field, which can be a Library, Class, or a
+  // Function.
+  @Library|@Class|@Function owner;
+
+  // What kind of function is this?
+  FunctionKind kind;
+
+  // Is this function static?
+  bool static
+
+  // Is this function const?
+  bool const;
+
+  // The script containing this function.
+  @Script script [optional];
+
+  // The first token position of this function.
+  int tokenPos [optional];
+
+  // The last token position of this function.
+  int endTokenPos [optional];
+
+  // The compiled code associated with this function.
+  @Code code [optional];
+}
+```
+
+A _Function_ represents a Dart language function.
+
+### FunctionKind
+
+```
+enum FunctionKind {
+  RegularFunction,
+  ClosureFunction,
+  GetterFunction,
+  SetterFunction,
+  Constructor,
+  ImplicitGetter,
+  ImplicitSetter,
+  ImplicitStaticFinalGetter,
+  IrregexpFunction,
+  StaticInitializer,
+  MethodExtractor,
+  NoSuchMethodDispatcher,
+  InvokeFieldDispatcher,
+  Collected,
+  Native,
+  Stub,
+  Tag
+}
+```
+
+TODO: Do we need to expose all of this?
+
+### Instance
+
+```
+class @Instance extends @Object {
+  // Instance references include their class.
+  @Class class;
+}
+```
+
+_@Instance_ is a reference to an _Instance_.
+
+```
+class Instance extends Object {
+  BoundField fields [optional];
+}
+```
+
+An _Instance_ represents an instance of the Dart language class _Object_.
+
+### Int
+
+```
+class @Int extends @Instance {
+  // The value of this int as a string.
+  //
+  // Suitable for passing to int.parse().
+  string valueAsString;
+}
+```
+
+_@Int_ is a reference to an _Int_.
+
+```
+class Int extends Instance {
+  // The value of this int as a string.
+  //
+  // Suitable for passing to int.parse().
+  string valueAsString;
+}
+```
+
+An _Int_ represents an instance of the Dart language class _int_.
+
+### Isolate
+
+```
+class @Isolate extends Response {
+  // The id which is passed to the getIsolate RPC to load this isolate.
+  string id;
+
+  // A numeric id for this isolate, represented as a string.  Unique.
+  string number;
+
+  // A name identifying this isolate.  Not guaranteed to be unique.
+  string name;
+}
+```
+
+_@Isolate_ is a reference to an _Isolate_ object.
+
+```
+class Isolate extends Response {
+  // The id which is passed to the getIsolate RPC to reload this
+  // isolate.
+  string id;
+
+  // A numeric id for this isolate, represented as a string.  Unique.
+  string number;
+
+  // A name identifying this isolate.  Not guaranteed to be unique.
+  string name;
+
+  // The time that the VM started in milliseconds since the epoch.
+  //
+  // Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
+  int startTime;
+
+  // The entry function for this isolate.
+  @Function entry [optional];
+
+  // The number of live ports for this isolate.
+  int livePorts;
+
+  // Will this isolate pause when exiting?
+  bool pauseOnExit;
+
+  // The last pause event delivered to the isolate.  If the isolate is
+  // running, this will be a resume event.
+  Event pauseEvent;
+
+  // The error that is causing this isolate to exit, if applicable.
+  Error error [optional];
+
+  // The root library for this isolate.
+  @Library rootLib;
+
+  // A list of all libraries for this isolate.
+  @Library[] libraries;
+
+  // A list of all breakpoints for this isolate.
+  Breakpoint[] breakpoints;
+}
+```
+
+An _Isolate_ object provides information about one isolate in the VM.
+
+### Library
+
+```
+class @Library extends @Object {
+  // The name of this library.
+  string name;
+
+  // The uri of this library.
+  string uri;
+}
+```
+
+_@Library_ is a reference to a _Library_.
+
+```
+class Library extends Object {
+  // The name of this library.
+  string name;
+
+  // The uri of this library.
+  string uri;
+
+  // A list of the imports for this library.
+  @Library[] imports;
+
+  // A list of the scripts which constitute this library.
+  @Script[] scripts;
+
+  // A list of the top-level variables in this library.
+  @Field[] variables;
+
+  // A list of the top-level functions in this library.
+  @Function[] functions;
+
+  // A list of all classes in this library.
+  @Class[] classes;
+}
+```
+
+A _Library_ provides information about a Dart language library.
+
+### List
+
+```
+class @List extends @Instance {
+  // The length of this list.
+  int length;
+}
+```
+
+_@List_ is a reference to a _List_.
+
+```
+class List extends Instance {
+  // The length of this list.
+  int length;
+
+  // The elements of this list.
+  ListElement[] elements;
+}
+```
+
+A _List_ represents an built-in instance of the Dart class _List_.
+User-defined lists will be represented as _Instance_.
+
+### ListElement
+
+```
+class ListElement {
+  int index;
+  @Instance|Sentinel value;
+}
+```
+
+### Message
+
+```
+class Message {
+  int index;
+  string name;
+  string messageObjectId;
+  int size;
+  int priority;
+  @Function handlerFunction [optional];
+  @Script handleScript [optional];
+  int handlerTokenPos [optional];
+}
+```
+
+### Null
+
+```
+class @Null extends @Instance {
+  // Always 'null'.
+  string valueAsString;
+}
+```
+
+_@Null_ is a reference to an a _Null_.
+
+```
+class Null extends Instance {
+  // Always 'null'.
+  string valueAsString;
+}
+```
+
+A _Null_ object represents the Dart language value null.
+
+### Object
+
+```
+class @Object extends Response {
+  // A unique identifier for an Object.  Passed to the
+  // getObject RPC to load this Object.
+  string id
+}
+```
+
+_@Object_ is a reference to a _Object_.
+
+```
+class Object extends Response {
+  // A unique identifier for an Object.  Passed to the
+  // getObject RPC to reload this Object.
+  //
+  // Some objects may get a new id when they are reloaded.
+  string id;
+
+  // Every object has a corresponding Class in the VM.
+  @Class class;
+
+  // The size of this object in the heap.
+  //
+  // Note that the size can be zero for some objects.
+  int size;
+}
+```
+
+An _Object_ is a  persistent object that is owned by some isolate.
+
+### Sentinel
+
+```
+class Sentinel extends Response {
+  // What kind of sentinel is this?
+  SentinelType sentinelType;
+
+  // A reasonable string representation of this sentinel.
+  string valueAsString;
+}
+```
+
+A _Sentinel_ is used to indicate that the normal response is not available.
+
+We use a _Sentinel_ instead of an [error](#errors) for these cases because
+they do not represent a problematic condition.  They are normal.
+
+### SentinelType
+
+```
+enum SentinelType {
+  // Indicates that the object referred to has been collected by the GC.
+  Collected,
+
+  // Indicates that an object id has expired.
+  Expired,
+
+  // Indicates that a variable or field has not been initialized.
+  NotInitialized,
+
+  // Indicates that a variable or field is in the process of being initialized.
+  BeingInitialized,
+
+  // Indicates that a variable has been eliminated by the optimizing compiler.
+  OptimizedOut
+}
+```
+
+A _SentinelType_ is used to distinguish different kinds of _Sentinel_ objects.
+
+### Script
+
+```
+class @Script extends @Object {
+  // The uri from which this script was loaded.
+  string uri;
+}
+```
+
+_@Script_ is a reference to a _Script_.
+
+```
+class Script extends Object {
+  // The uri from which this script was loaded.
+  string uri;
+
+  // The library which owns this script.
+  @Library library;
+
+  // The source code for this script.  For certain built-in scripts,
+  // this may be reconstructed without source comments.
+  string source;
+
+  // A table encoding a mapping from token position to line and column.
+  int[][] tokenPosTable;
+}
+```
+
+A _Script_ provides information about a Dart language script.
+
+The _tokenPosTable_ is an array of int arrays.  Each subarray
+consists of a line number followed by _(tokenPos, columnNumber)_ pairs:
+
+> [lineNumber, (tokenPos, columnNumber)*]
+
+For example, a _tokenPosTable_ with the value...
+
+> [[1, 100, 5, 101, 8],[2, 102, 7]]
+
+...encodes the mapping:
+
+tokenPos | line | column
+-------- | ---- | ------
+100 | 1 | 5
+101 | 1 | 8
+102 | 2 | 7
+
+### Stack
+
+```
+class Stack {
+  Frame[] frames;
+  Message[] messages;
+}
+```
+
+### StepOption
+
+```
+enum StepOption {
+  into,
+  over,
+  out
+}
+```
+
+A _StepOption_ indicates which form of stepping is requested in a [resume](#resume) RPC.
+
+### String
+
+```
+class @String extends @Instance {
+  // The value of this double as a string.
+  //
+  // Note that this may be truncated.
+  //
+  // Suitable for passing to double.parse().
+  string valueAsString;
+
+  // The valueAsString for String references may be truncated.  If so,
+  // this property is added with the value 'true'.
+  bool valueAsStringIsTruncated [optional];
+}
+```
+
+_@String_ is a reference to a _String_.
+
+```
+class String extends Instance {
+  // The value of this double as a string.
+  //
+  // Note that this will never be truncated.
+  //
+  // Suitable for passing to double.parse().
+  string valueAsString;
+}
+```
+
+An _String_ represents an instance of the Dart language class _String_.
+
+The _valueAsString_ property for an _@String_ may be truncated.  To get
+the untruncated _valueAsString_, call the [getObject](#getobject) RPC
+on the String's _id_.  A _String_ object never truncates the
+_valueAsString_.
+
+### Success
+
+```
+class Success extends Response {
+}
+```
+
+The _Success_ type is used to indicate that an operation completed successfully.
+
+### Type
+
+```
+class @Type extends @Instance {
+  // The name of this type.
+  string name;
+
+  // The corresponding Class if this Type is canonical.
+  @Class typeClass [optional];
+}
+```
+
+_@Type_ is a reference to a _Type_.
+
+```
+class Type extends Instance {
+  // The name of this type.
+  string name;
+
+  // The corresponding Class if this Type is canonical.
+  @Class typeClass [optional];
+
+  // The type arguments for this type.
+  @TypeArguments typeArgs [optional];
+}
+```
+
+An _Type_ represents an instance of the Dart language class _Type_.
+
+### TypeArguments
+
+```
+class @TypeArguments extends @Object {
+  // A name for this type argument list.
+  string name;
+}
+```
+
+_@TypeArguments_ is a reference to a _TypeArguments_ object.
+
+```
+class TypeArguments extends Object {
+  // A name for this type argument list.
+  string name;
+
+  // A list of types.
+  @Type[] types;
+}
+```
+
+A _TypeArguments_ object represents the type argument vector for some
+instantiated generic type.
+
+### Response
+
+```
+class Response {
+  // Every response returned by the VM Service has the
+  // type property.  This allows the client distinguish
+  // between different kinds of responses.
+  string type;
+}
+```
+
+Every non-error response returned by the Service Protocol extends _Response_.
+By using the _type_ property, the client can determine which [type](#types)
+of response has been provided.
+
+### Version
+
+```
+class Version extends Response {
+  // The major version number is incremented when the protocol is changed
+  // in a potentially incompatible way.
+  int major;
+
+  // The minor version number is incremented when the protocol is changed
+  // in a backwards compatible way.
+  int minor;
+}
+```
+
+See [Versioning](#versioning).
+
+### VM
+
+```
+class VM extends Response {
+  // Word length on target architecture (e.g. 32, 64).
+  int architectureBits;
+
+  // The CPU we are generating code for.
+  string targetCPU;
+
+  // The CPU we are actually running on.
+  string hostCPU;
+
+  // The Dart VM version string.
+  string version;
+
+  // The process id for the VM.
+  string pid;
+
+  // The time that the VM started in milliseconds since the epoch.
+  //
+  // Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
+  int startTime
+
+  // A list of isolates running in the VM.
+  @Isolate[] isolates
+}
+```
+
+## Revision History
+
+version | comments
+------- | --------
+0.0 | draft
diff --git a/runtime/vm/service_event.h b/runtime/vm/service_event.h
index e74ee66..0c90d00 100644
--- a/runtime/vm/service_event.h
+++ b/runtime/vm/service_event.h
@@ -50,10 +50,10 @@
 
   EventType type() const { return type_; }
 
-  SourceBreakpoint* breakpoint() const {
+  Breakpoint* breakpoint() const {
     return breakpoint_;
   }
-  void set_breakpoint(SourceBreakpoint* bpt) {
+  void set_breakpoint(Breakpoint* bpt) {
     ASSERT(type() == kPauseBreakpoint ||
            type() == kBreakpointAdded ||
            type() == kBreakpointResolved ||
@@ -103,7 +103,7 @@
  private:
   Isolate* isolate_;
   EventType type_;
-  SourceBreakpoint* breakpoint_;
+  Breakpoint* breakpoint_;
   ActivationFrame* top_frame_;
   const Object* exception_;
   const Object* inspectee_;
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 3665cf3..faffd66 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -219,7 +219,7 @@
  public:
   static void SendIsolateServiceMessage(Dart_NativeArguments args) {
     NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-    Isolate* isolate = arguments->isolate();
+    Isolate* isolate = arguments->thread()->isolate();
     StackZone stack_zone(isolate);
     Zone* zone = stack_zone.GetZone();  // Used by GET_NON_NULL_NATIVE_ARGUMENT.
     HANDLESCOPE(isolate);
@@ -243,7 +243,7 @@
 
   static void SendRootServiceMessage(Dart_NativeArguments args) {
     NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-    Isolate* isolate = arguments->isolate();
+    Isolate* isolate = arguments->thread()->isolate();
     StackZone stack_zone(isolate);
     Zone* zone = stack_zone.GetZone();  // Used by GET_NON_NULL_NATIVE_ARGUMENT.
     HANDLESCOPE(isolate);
@@ -253,7 +253,7 @@
 
   static void OnStart(Dart_NativeArguments args) {
     NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-    Isolate* isolate = arguments->isolate();
+    Isolate* isolate = arguments->thread()->isolate();
     StackZone zone(isolate);
     HANDLESCOPE(isolate);
     {
@@ -287,7 +287,7 @@
 
   static void OnExit(Dart_NativeArguments args) {
     NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-    Isolate* isolate = arguments->isolate();
+    Isolate* isolate = arguments->thread()->isolate();
     StackZone zone(isolate);
     HANDLESCOPE(isolate);
     {
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index 07ef1e2..f6a20a1 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -209,7 +209,8 @@
     const intptr_t kBufferSize = 512;
     char buffer[kBufferSize];
     OS::SNPrint(buffer, kBufferSize-1,
-                "{\"type\":\"Code\",\"id\":\"code\\/%" Px64 "-%" Px "\",",
+                "{\"type\":\"Code\",\"fixedId\":true,"
+                "\"id\":\"code\\/%" Px64 "-%" Px "\",",
                 compile_timestamp,
                 entry);
     EXPECT_SUBSTRING(buffer, handler.msg());
@@ -244,7 +245,8 @@
                       address);
   Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
-  EXPECT_SUBSTRING("{\"type\":\"null\",\"id\":\"objects\\/null\","
+  EXPECT_SUBSTRING("{\"type\":\"null\",\"fixedId\":true,"
+                   "\"id\":\"objects\\/null\","
                    "\"valueAsString\":\"null\"",
                    handler.msg());
 
@@ -457,9 +459,9 @@
     bool ref = offset % 2 == 0;
     OS::SNPrint(buf, sizeof(buf),
                 (ref
-                 ? "[0, port, '0', 'getObjectByAddress', "
+                 ? "[0, port, '0', '_getObjectByAddress', "
                    "['address', 'ref'], ['%" Px "', 'true']]"
-                 : "[0, port, '0', 'getObjectByAddress', "
+                 : "[0, port, '0', '_getObjectByAddress', "
                    "['address'], ['%" Px "']]"),
                 addr);
     service_msg = Eval(lib, buf);
@@ -471,7 +473,7 @@
     EXPECT_SUBSTRING("foobar", handler.msg());
   }
   // Expect null when no object is found.
-  service_msg = Eval(lib, "[0, port, '0', 'getObjectByAddress', "
+  service_msg = Eval(lib, "[0, port, '0', '_getObjectByAddress', "
                      "['address'], ['7']]");
   Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
@@ -533,11 +535,13 @@
   service_msg = Eval(lib, "[0, port, '0', 'alpha', [], []]");
   Service::HandleRootMessage(service_msg);
   handler.HandleNextMessage();
-  EXPECT_STREQ("{\"result\":alpha, \"id\":\"0\"}", handler.msg());
+  EXPECT_STREQ("{\"json-rpc\":\"2.0\", \"result\":alpha, \"id\":\"0\"}",
+               handler.msg());
   service_msg = Eval(lib, "[0, port, '0', 'beta', [], []]");
   Service::HandleRootMessage(service_msg);
   handler.HandleNextMessage();
-  EXPECT_STREQ("{\"result\":beta, \"id\":\"0\"}", handler.msg());
+  EXPECT_STREQ("{\"json-rpc\":\"2.0\", \"result\":beta, \"id\":\"0\"}",
+               handler.msg());
 }
 
 
@@ -571,11 +575,13 @@
   service_msg = Eval(lib, "[0, port, '0', 'alpha', [], []]");
   Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
-  EXPECT_STREQ("{\"result\":alpha, \"id\":\"0\"}", handler.msg());
+  EXPECT_STREQ("{\"json-rpc\":\"2.0\", \"result\":alpha, \"id\":\"0\"}",
+               handler.msg());
   service_msg = Eval(lib, "[0, port, '0', 'beta', [], []]");
   Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
-  EXPECT_STREQ("{\"result\":beta, \"id\":\"0\"}", handler.msg());
+  EXPECT_STREQ("{\"json-rpc\":\"2.0\", \"result\":beta, \"id\":\"0\"}",
+               handler.msg());
 }
 
 // TODO(zra): Remove when tests are ready to enable.
@@ -605,21 +611,21 @@
   EXPECT_VALID(Dart_SetField(lib, NewString("port"), port));
 
   Array& service_msg = Array::Handle();
-  service_msg = Eval(lib, "[0, port, '0', 'getCpuProfile', [], []]");
+  service_msg = Eval(lib, "[0, port, '0', '_getCpuProfile', [], []]");
   Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   // Expect error (tags required).
   EXPECT_SUBSTRING("\"error\"", handler.msg());
 
   service_msg =
-      Eval(lib, "[0, port, '0', 'getCpuProfile', ['tags'], ['None']]");
+      Eval(lib, "[0, port, '0', '_getCpuProfile', ['tags'], ['None']]");
   Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   // Expect profile
   EXPECT_SUBSTRING("\"type\":\"_CpuProfile\"", handler.msg());
 
   service_msg =
-      Eval(lib, "[0, port, '0', 'getCpuProfile', ['tags'], ['Bogus']]");
+      Eval(lib, "[0, port, '0', '_getCpuProfile', ['tags'], ['Bogus']]");
   Service::HandleIsolateMessage(isolate, service_msg);
   handler.HandleNextMessage();
   // Expect error.
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index d329434..42ae595 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -1526,7 +1526,7 @@
         if (redirection->call_kind() == kRuntimeCall) {
           NativeArguments arguments;
           ASSERT(sizeof(NativeArguments) == 4*kWordSize);
-          arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0));
+          arguments.thread_ = reinterpret_cast<Thread*>(get_register(R0));
           arguments.argc_tag_ = get_register(R1);
           arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2));
           arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3));
@@ -3846,7 +3846,7 @@
                         uword fp,
                         RawObject* raw_exception,
                         RawObject* raw_stacktrace,
-                        Isolate* isolate) {
+                        Thread* thread) {
   // Walk over all setjmp buffers (simulated --> C++ transitions)
   // and try to find the setjmp associated with the simulated stack pointer.
   SimulatorSetjmpBuffer* buf = last_setjmp_buffer();
@@ -3858,12 +3858,14 @@
   // The C++ caller has not cleaned up the stack memory of C++ frames.
   // Prepare for unwinding frames by destroying all the stack resources
   // in the previous C++ frames.
+  Isolate* isolate = thread->isolate();
   StackResource::Unwind(isolate);
 
   // Unwind the C++ stack and continue simulation in the target frame.
   set_register(PC, static_cast<int32_t>(pc));
   set_register(SP, static_cast<int32_t>(sp));
   set_register(FP, static_cast<int32_t>(fp));
+  set_register(THR, reinterpret_cast<uword>(thread));
   // Set the tag.
   isolate->set_vm_tag(VMTag::kDartTagId);
   // Clear top exit frame.
diff --git a/runtime/vm/simulator_arm.h b/runtime/vm/simulator_arm.h
index 3e660b6..712e679 100644
--- a/runtime/vm/simulator_arm.h
+++ b/runtime/vm/simulator_arm.h
@@ -125,7 +125,7 @@
                uword fp,
                RawObject* raw_exception,
                RawObject* raw_stacktrace,
-               Isolate* isolate);
+               Thread* thread);
 
  private:
   // Known bad pc value to ensure that the simulator does not execute
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 2d0cbd3..0a8775e 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -3506,7 +3506,7 @@
                         uword fp,
                         RawObject* raw_exception,
                         RawObject* raw_stacktrace,
-                        Isolate* isolate) {
+                        Thread* thread) {
   // Walk over all setjmp buffers (simulated --> C++ transitions)
   // and try to find the setjmp associated with the simulated stack pointer.
   SimulatorSetjmpBuffer* buf = last_setjmp_buffer();
@@ -3518,12 +3518,14 @@
   // The C++ caller has not cleaned up the stack memory of C++ frames.
   // Prepare for unwinding frames by destroying all the stack resources
   // in the previous C++ frames.
+  Isolate* isolate = thread->isolate();
   StackResource::Unwind(isolate);
 
   // Unwind the C++ stack and continue simulation in the target frame.
   set_pc(static_cast<int64_t>(pc));
   set_register(NULL, SP, static_cast<int64_t>(sp));
   set_register(NULL, FP, static_cast<int64_t>(fp));
+  set_register(NULL, THR, reinterpret_cast<int64_t>(thread));
   // Set the tag.
   isolate->set_vm_tag(VMTag::kDartTagId);
   // Clear top exit frame.
diff --git a/runtime/vm/simulator_arm64.h b/runtime/vm/simulator_arm64.h
index 6a1bd8b..ceecb49 100644
--- a/runtime/vm/simulator_arm64.h
+++ b/runtime/vm/simulator_arm64.h
@@ -122,7 +122,7 @@
                uword fp,
                RawObject* raw_exception,
                RawObject* raw_stacktrace,
-               Isolate* isolate);
+               Thread* thread);
 
  private:
   // Known bad pc value to ensure that the simulator does not execute
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index cd351a7..684d81da 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -1237,7 +1237,7 @@
       if (redirection->call_kind() == kRuntimeCall) {
         NativeArguments arguments;
         ASSERT(sizeof(NativeArguments) == 4*kWordSize);
-        arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(A0));
+        arguments.thread_ = reinterpret_cast<Thread*>(get_register(A0));
         arguments.argc_tag_ = get_register(A1);
         arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(A2));
         arguments.retval_ = reinterpret_cast<RawObject**>(get_register(A3));
@@ -2454,7 +2454,7 @@
                         uword fp,
                         RawObject* raw_exception,
                         RawObject* raw_stacktrace,
-                        Isolate* isolate) {
+                        Thread* thread) {
   // Walk over all setjmp buffers (simulated --> C++ transitions)
   // and try to find the setjmp associated with the simulated stack pointer.
   SimulatorSetjmpBuffer* buf = last_setjmp_buffer();
@@ -2466,12 +2466,14 @@
   // The C++ caller has not cleaned up the stack memory of C++ frames.
   // Prepare for unwinding frames by destroying all the stack resources
   // in the previous C++ frames.
+  Isolate* isolate = thread->isolate();
   StackResource::Unwind(isolate);
 
   // Unwind the C++ stack and continue simulation in the target frame.
   set_pc(static_cast<int32_t>(pc));
   set_register(SP, static_cast<int32_t>(sp));
   set_register(FP, static_cast<int32_t>(fp));
+  set_register(THR, reinterpret_cast<int32_t>(thread));
   // Set the tag.
   isolate->set_vm_tag(VMTag::kDartTagId);
   // Clear top exit frame.
diff --git a/runtime/vm/simulator_mips.h b/runtime/vm/simulator_mips.h
index 23972fe..4243072 100644
--- a/runtime/vm/simulator_mips.h
+++ b/runtime/vm/simulator_mips.h
@@ -141,7 +141,7 @@
                uword fp,
                RawObject* raw_exception,
                RawObject* raw_stacktrace,
-               Isolate* isolate);
+               Thread* thread);
 
  private:
   // A pc value used to signal the simulator to stop execution.  Generally
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 8f3d2a6..93ca5e8 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -1184,6 +1184,13 @@
     // Read in the symbol table.
     object_store->symbol_table_ = reinterpret_cast<RawArray*>(ReadObject());
 
+    Symbols::InitOnceFromSnapshot(isolate);
+
+    // Read in all the script objects and the accompanying token streams
+    // for bootstrap libraries so that they are in the VM isolate's read
+    // only memory.
+    *(ArrayHandle()) ^= ReadObject();
+
     // Validate the class table.
 #if defined(DEBUG)
     isolate->ValidateClassTable();
@@ -1466,6 +1473,43 @@
 }
 
 
+// An object visitor which will iterate over all the script objects in the heap
+// and either count them or collect them into an array. This is used during
+// full snapshot generation of the VM isolate to write out all script
+// objects and their accompanying token streams.
+class ScriptVisitor : public ObjectVisitor {
+ public:
+  explicit ScriptVisitor(Isolate* isolate) :
+      ObjectVisitor(isolate),
+      objHandle_(Object::Handle(isolate)),
+      count_(0),
+      scripts_(NULL) {}
+
+  ScriptVisitor(Isolate* isolate, const Array* scripts) :
+      ObjectVisitor(isolate),
+      objHandle_(Object::Handle(isolate)),
+      count_(0),
+      scripts_(scripts) {}
+
+  void VisitObject(RawObject* obj) {
+    if (obj->IsScript()) {
+      if (scripts_ != NULL) {
+        objHandle_ = obj;
+        scripts_->SetAt(count_, objHandle_);
+      }
+      count_ += 1;
+    }
+  }
+
+  intptr_t count() const { return count_; }
+
+ private:
+  Object& objHandle_;
+  intptr_t count_;
+  const Array* scripts_;
+};
+
+
 void FullSnapshotWriter::WriteVmIsolateSnapshot() {
   ASSERT(vm_isolate_snapshot_buffer_ != NULL);
   SnapshotWriter writer(Snapshot::kFull,
@@ -1485,7 +1529,18 @@
   isolate->ValidateClassTable();
 #endif
 
-  // Write full snapshot for a regular isolate.
+  // Collect all the script objects and their accompanying token stream objects
+  // into an array so that we can write it out as part of the VM isolate
+  // snapshot. We first count the number of script objects, allocate an array
+  // and then fill it up with the script objects.
+  ScriptVisitor scripts_counter(isolate);
+  isolate->heap()->old_space()->VisitObjects(&scripts_counter);
+  intptr_t count = scripts_counter.count();
+  const Array& scripts = Array::Handle(isolate, Array::New(count, Heap::kOld));
+  ScriptVisitor script_visitor(isolate, &scripts);
+  isolate->heap()->old_space()->VisitObjects(&script_visitor);
+
+  // Write full snapshot for the VM isolate.
   // Setup for long jump in case there is an exception while writing
   // the snapshot.
   LongJumpScope jump;
@@ -1496,7 +1551,12 @@
     // Write out the version string.
     writer.WriteVersion();
 
-    // Write out the symbol table.
+    /*
+     * Now Write out the following
+     * - the symbol table
+     * - all the scripts and token streams for these scripts
+     *
+     **/
     {
       NoSafepointScope no_safepoint;
 
@@ -1505,6 +1565,14 @@
       // snapshot of a regular dart isolate.
       writer.WriteObject(object_store->symbol_table());
 
+      // Write out all the script objects and the accompanying token streams
+      // for the bootstrap libraries so that they are in the VM isolate
+      // read only memory.
+      writer.WriteObject(scripts.raw());
+
+      // Write out all forwarded objects.
+      writer.WriteForwardedObjects();
+
       writer.FillHeader(writer.kind());
     }
     vm_isolate_snapshot_size_ = writer.BytesWritten();
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index abe0b8e..6707566 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -19,6 +19,7 @@
 namespace dart {
 
 DECLARE_FLAG(bool, enable_type_checks);
+DECLARE_FLAG(bool, load_deferred_eagerly);
 
 // Check if serialized and deserialized objects are equal.
 static bool Equals(const Object& expected, const Object& actual) {
@@ -1232,6 +1233,9 @@
   intptr_t expected_num_libs;
   intptr_t actual_num_libs;
 
+  bool saved_load_deferred_eagerly_mode = FLAG_load_deferred_eagerly;
+  FLAG_load_deferred_eagerly = true;
+
   {
     // Start an Isolate, and create a full snapshot of it.
     TestIsolateScope __test_isolate__;
@@ -1248,6 +1252,7 @@
     Dart_ExitScope();
   }
 
+  FLAG_load_deferred_eagerly = saved_load_deferred_eagerly_mode;
   {
     // Create an Isolate using the full snapshot, load a script and create
     // a script snapshot of the script.
@@ -1328,6 +1333,8 @@
   uint8_t* full_snapshot = NULL;
   uint8_t* script_snapshot = NULL;
 
+  bool saved_load_deferred_eagerly_mode = FLAG_load_deferred_eagerly;
+  FLAG_load_deferred_eagerly = true;
   {
     // Start an Isolate, and create a full snapshot of it.
     TestIsolateScope __test_isolate__;
@@ -1373,6 +1380,8 @@
     result = Dart_LoadScriptFromSnapshot(script_snapshot, size);
     EXPECT_VALID(result);
   }
+
+  FLAG_load_deferred_eagerly = saved_load_deferred_eagerly_mode;
   Dart_ShutdownIsolate();
   free(full_snapshot);
   free(script_snapshot);
@@ -1412,8 +1421,10 @@
   uint8_t* script_snapshot = NULL;
 
   // Force creation of snapshot in production mode.
-  bool saved_mode = FLAG_enable_type_checks;
+  bool saved_enable_type_checks_mode = FLAG_enable_type_checks;
   FLAG_enable_type_checks = false;
+  bool saved_load_deferred_eagerly_mode = FLAG_load_deferred_eagerly;
+  FLAG_load_deferred_eagerly = true;
 
   {
     // Start an Isolate, and create a full snapshot of it.
@@ -1461,7 +1472,8 @@
   }
 
   // Continue in originally saved mode.
-  FLAG_enable_type_checks = saved_mode;
+  FLAG_enable_type_checks = saved_enable_type_checks_mode;
+  FLAG_load_deferred_eagerly = saved_load_deferred_eagerly_mode;
 
   {
     // Now Create an Isolate using the full snapshot and load the
@@ -1476,15 +1488,15 @@
 
     // Invoke the test_s function.
     result = Dart_Invoke(lib, NewString("test_s"), 0, NULL);
-    EXPECT(Dart_IsError(result) == saved_mode);
+    EXPECT(Dart_IsError(result) == saved_enable_type_checks_mode);
 
     // Invoke the test_i function.
     result = Dart_Invoke(lib, NewString("test_i"), 0, NULL);
-    EXPECT(Dart_IsError(result) == saved_mode);
+    EXPECT(Dart_IsError(result) == saved_enable_type_checks_mode);
 
     // Invoke the test_b function.
     result = Dart_Invoke(lib, NewString("test_b"), 0, NULL);
-    EXPECT(Dart_IsError(result) == saved_mode);
+    EXPECT(Dart_IsError(result) == saved_enable_type_checks_mode);
   }
   Dart_ShutdownIsolate();
   free(full_snapshot);
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index a45216d..a618111 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -50,7 +50,6 @@
   V(UpdateStoreBuffer)                                                         \
   V(OneArgCheckInlineCache)                                                    \
   V(TwoArgsCheckInlineCache)                                                   \
-  V(ThreeArgsCheckInlineCache)                                                 \
   V(SmiAddInlineCache)                                                         \
   V(SmiSubInlineCache)                                                         \
   V(SmiEqualInlineCache)                                                       \
@@ -58,7 +57,6 @@
   V(BinaryRangeCollectingInlineCache)                                          \
   V(OneArgOptimizedCheckInlineCache)                                           \
   V(TwoArgsOptimizedCheckInlineCache)                                          \
-  V(ThreeArgsOptimizedCheckInlineCache)                                        \
   V(ZeroArgsUnoptimizedStaticCall)                                             \
   V(OneArgUnoptimizedStaticCall)                                               \
   V(TwoArgsUnoptimizedStaticCall)                                              \
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 1d438ec..e7e6a66 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -37,7 +37,7 @@
 //   R5 : address of the runtime function to call.
 //   R4 : number of arguments to the call.
 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
-  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t thread_offset = NativeArguments::thread_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
@@ -52,7 +52,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset());
+  __ StoreToOffset(kWord, FP, R9, Isolate::top_exit_frame_info_offset());
 
 #if defined(DEBUG)
   { Label ok;
@@ -76,9 +76,9 @@
   // Pass NativeArguments structure by value and call runtime.
   // Registers R0, R1, R2, and R3 are used.
 
-  ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs.
-  __ mov(R0, Operand(R9));
+  ASSERT(thread_offset == 0 * kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, Operand(THR));
 
   // There are no runtime calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -137,7 +137,7 @@
 //   R2 : address of first argument in argument array.
 //   R1 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
-  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t thread_offset = NativeArguments::thread_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
@@ -151,7 +151,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset());
+  __ StoreToOffset(kWord, FP, R9, Isolate::top_exit_frame_info_offset());
 
 #if defined(DEBUG)
   { Label ok;
@@ -175,9 +175,9 @@
   // Initialize NativeArguments structure and call native function.
   // Registers R0, R1, R2, and R3 are used.
 
-  ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs.
-  __ mov(R0, Operand(R9));
+  ASSERT(thread_offset == 0 * kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, Operand(THR));
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -230,7 +230,7 @@
 //   R2 : address of first argument in argument array.
 //   R1 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
-  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t thread_offset = NativeArguments::thread_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
@@ -244,7 +244,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset());
+  __ StoreToOffset(kWord, FP, R9, Isolate::top_exit_frame_info_offset());
 
 #if defined(DEBUG)
   { Label ok;
@@ -268,9 +268,9 @@
   // Initialize NativeArguments structure and call native function.
   // Registers R0, R1, R2, and R3 are used.
 
-  ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs.
-  __ mov(R0, Operand(R9));
+  ASSERT(thread_offset == 0 * kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, Operand(THR));
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -629,12 +629,12 @@
   __ b(&slow_case, GT);
 
   const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
-  __ LoadImmediate(R8, fixed_size);
-  __ add(R8, R8, Operand(R3, LSL, 1));  // R3 is  a Smi.
+  __ LoadImmediate(R9, fixed_size);
+  __ add(R9, R9, Operand(R3, LSL, 1));  // R3 is  a Smi.
   ASSERT(kSmiTagShift == 1);
-  __ bic(R8, R8, Operand(kObjectAlignment - 1));
+  __ bic(R9, R9, Operand(kObjectAlignment - 1));
 
-  // R8: Allocation size.
+  // R9: Allocation size.
 
   Isolate* isolate = Isolate::Current();
   Heap* heap = isolate->heap();
@@ -642,13 +642,13 @@
   Heap::Space space = heap->SpaceForAllocation(cid);
   __ LoadImmediate(R6, heap->TopAddress(space));
   __ ldr(R0, Address(R6, 0));  // Potential new object start.
-  __ adds(R7, R0, Operand(R8));  // Potential next object start.
+  __ adds(R7, R0, Operand(R9));  // Potential next object start.
   __ b(&slow_case, CS);  // Branch if unsigned overflow.
 
   // Check if the allocation fits into the remaining space.
   // R0: potential new object start.
   // R7: potential next object start.
-  // R8: allocation size.
+  // R9: allocation size.
   __ LoadImmediate(R3, heap->EndAddress(space));
   __ ldr(R3, Address(R3, 0));
   __ cmp(R7, Operand(R3));
@@ -664,12 +664,12 @@
   // R0: new object start as a tagged pointer.
   // R3: allocation stats address.
   // R7: new object end address.
-  // R8: allocation size.
+  // R9: allocation size.
   {
     const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
 
-    __ CompareImmediate(R8, RawObject::SizeTag::kMaxSizeTag);
-    __ mov(R6, Operand(R8, LSL, shift), LS);
+    __ CompareImmediate(R9, RawObject::SizeTag::kMaxSizeTag);
+    __ mov(R6, Operand(R9, LSL, shift), LS);
     __ mov(R6, Operand(0), HI);
 
     // Get the class index and insert it into the tags.
@@ -698,13 +698,13 @@
   // R6: iterator which initially points to the start of the variable
   // data area to be initialized.
   // R7: new object end address.
-  // R8: allocation size.
+  // R9: allocation size.
 
   __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null()));
   __ mov(R5, Operand(R4));
   __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag);
   __ InitializeFieldsNoBarrier(R0, R6, R7, R4, R5);
-  __ IncrementAllocationStatsWithSize(R3, R8, cid, space);
+  __ IncrementAllocationStatsWithSize(R3, R9, cid, space);
   __ Ret();  // Returns the newly allocated object in R0.
   // Unable to allocate the array using the fast inline code, just call
   // into the runtime.
@@ -735,7 +735,7 @@
 //   R0 : entrypoint of the Dart function to call.
 //   R1 : arguments descriptor array.
 //   R2 : arguments array.
-//   R3 : new context containing the current isolate pointer.
+//   R3 : current thread.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
   // Save frame pointer coming in.
   __ EnterFrame((1 << FP) | (1 << LR), 0);
@@ -757,23 +757,27 @@
   // set up.
   __ LoadPoolPointer();
 
-  __ LoadIsolate(R8);
+  // Set up THR, which caches the current thread in Dart code.
+  if (THR != R3) {
+    __ mov(THR, Operand(R3));
+  }
+  __ LoadIsolate(R9);
 
   // Save the current VMTag on the stack.
-  __ LoadFromOffset(kWord, R5, R8, Isolate::vm_tag_offset());
+  __ LoadFromOffset(kWord, R5, R9, Isolate::vm_tag_offset());
   __ Push(R5);
 
   // Mark that the isolate is executing Dart code.
   __ LoadImmediate(R5, VMTag::kDartTagId);
-  __ StoreToOffset(kWord, R5, R8, Isolate::vm_tag_offset());
+  __ StoreToOffset(kWord, R5, R9, Isolate::vm_tag_offset());
 
   // Save top resource and top exit frame info. Use R4-6 as temporary registers.
   // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ LoadFromOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset());
-  __ LoadFromOffset(kWord, R4, R8, Isolate::top_resource_offset());
+  __ LoadFromOffset(kWord, R5, R9, Isolate::top_exit_frame_info_offset());
+  __ LoadFromOffset(kWord, R4, R9, Isolate::top_resource_offset());
   __ LoadImmediate(R6, 0);
-  __ StoreToOffset(kWord, R6, R8, Isolate::top_resource_offset());
-  __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset());
+  __ StoreToOffset(kWord, R6, R9, Isolate::top_resource_offset());
+  __ StoreToOffset(kWord, R6, R9, Isolate::top_exit_frame_info_offset());
 
   // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
   __ Push(R4);
@@ -812,17 +816,17 @@
   // Get rid of arguments pushed on the stack.
   __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
 
-  __ LoadIsolate(R8);
+  __ LoadIsolate(R9);
   // Restore the saved top exit frame info and top resource back into the
   // Isolate structure. Uses R5 as a temporary register for this.
   __ Pop(R5);
-  __ StoreToOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset());
+  __ StoreToOffset(kWord, R5, R9, Isolate::top_exit_frame_info_offset());
   __ Pop(R5);
-  __ StoreToOffset(kWord, R5, R8, Isolate::top_resource_offset());
+  __ StoreToOffset(kWord, R5, R9, Isolate::top_resource_offset());
 
   // Restore the current VMTag from the stack.
   __ Pop(R4);
-  __ StoreToOffset(kWord, R4, R8, Isolate::vm_tag_offset());
+  __ StoreToOffset(kWord, R4, R9, Isolate::vm_tag_offset());
 
   // Restore C++ ABI callee-saved registers.
   if (TargetCPUFeatures::vfp_supported()) {
@@ -1545,16 +1549,6 @@
 }
 
 
-void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler,
-      3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
-}
-
-
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler,
@@ -1619,15 +1613,6 @@
 }
 
 
-void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
-}
-
-
 // Intermediary stub between a static call and its target. ICData contains
 // the target function and the call count.
 // R5: ICData
@@ -1912,7 +1897,7 @@
 // R2: frame_pointer.
 // R3: error object.
 // SP + 0: address of stacktrace object.
-// SP + 4: isolate
+// SP + 4: thread.
 // Does not return.
 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
   ASSERT(kExceptionObjectReg == R0);
@@ -1921,9 +1906,10 @@
   __ mov(LR, Operand(R0));  // Program counter.
   __ mov(R0, Operand(R3));  // Exception object.
   __ ldr(R1, Address(SP, 0));  // StackTrace object.
-  __ ldr(R3, Address(SP, 4));  // Isolate.
+  __ ldr(THR, Address(SP, 4));  // Thread.
   __ mov(FP, Operand(R2));  // Frame_pointer.
   __ mov(SP, Operand(IP));  // Set Stack pointer.
+  __ LoadIsolate(R3);
   // Set the tag.
   __ LoadImmediate(R2, VMTag::kDartTagId);
   __ StoreToOffset(kWord, R2, R3, Isolate::vm_tag_offset());
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 745c8cd..e443039 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -36,7 +36,7 @@
 //   R5 : address of the runtime function to call.
 //   R4 : number of arguments to the call.
 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
-  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t thread_offset = NativeArguments::thread_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
@@ -51,7 +51,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
+  __ StoreToOffset(FP, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
 
 #if defined(DEBUG)
   { Label ok;
@@ -77,9 +77,9 @@
   // Pass NativeArguments structure by value and call runtime.
   // Registers R0, R1, R2, and R3 are used.
 
-  ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs.
-  __ mov(R0, R28);
+  ASSERT(thread_offset == 0 * kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, THR);
 
   // There are no runtime calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -95,7 +95,7 @@
     ASSERT(retval_offset == 3 * kWordSize);
   __ AddImmediate(R3, R2, kWordSize, kNoPP);
 
-  __ StoreToOffset(R0, SP, isolate_offset, kNoPP);
+  __ StoreToOffset(R0, SP, thread_offset, kNoPP);
   __ StoreToOffset(R1, SP, argc_tag_offset, kNoPP);
   __ StoreToOffset(R2, SP, argv_offset, kNoPP);
   __ StoreToOffset(R3, SP, retval_offset, kNoPP);
@@ -139,7 +139,7 @@
 //   R2 : address of first argument in argument array.
 //   R1 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
-  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t thread_offset = NativeArguments::thread_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
@@ -151,7 +151,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
+  __ StoreToOffset(FP, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
 
 #if defined(DEBUG)
   { Label ok;
@@ -175,9 +175,9 @@
   // Initialize NativeArguments structure and call native function.
   // Registers R0, R1, R2, and R3 are used.
 
-  ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs.
-  __ mov(R0, R28);
+  ASSERT(thread_offset == 0 * kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, THR);
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -194,7 +194,7 @@
   // Passing the structure by value as in runtime calls would require changing
   // Dart API for native functions.
   // For now, space is reserved on the stack and we pass a pointer to it.
-  __ StoreToOffset(R0, SP, isolate_offset, kNoPP);
+  __ StoreToOffset(R0, SP, thread_offset, kNoPP);
   __ StoreToOffset(R1, SP, argc_tag_offset, kNoPP);
   __ StoreToOffset(R2, SP, argv_offset, kNoPP);
   __ StoreToOffset(R3, SP, retval_offset, kNoPP);
@@ -241,7 +241,7 @@
 //   R2 : address of first argument in argument array.
 //   R1 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
-  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t thread_offset = NativeArguments::thread_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
@@ -253,7 +253,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
+  __ StoreToOffset(FP, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
 
 #if defined(DEBUG)
   { Label ok;
@@ -277,9 +277,9 @@
   // Initialize NativeArguments structure and call native function.
   // Registers R0, R1, R2, and R3 are used.
 
-  ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs.
-  __ mov(R0, R28);
+  ASSERT(thread_offset == 0 * kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, THR);
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -296,7 +296,7 @@
   // Passing the structure by value as in runtime calls would require changing
   // Dart API for native functions.
   // For now, space is reserved on the stack and we pass a pointer to it.
-  __ StoreToOffset(R0, SP, isolate_offset, kNoPP);
+  __ StoreToOffset(R0, SP, thread_offset, kNoPP);
   __ StoreToOffset(R1, SP, argc_tag_offset, kNoPP);
   __ StoreToOffset(R2, SP, argv_offset, kNoPP);
   __ StoreToOffset(R3, SP, retval_offset, kNoPP);
@@ -770,7 +770,7 @@
 //   R0 : entrypoint of the Dart function to call.
 //   R1 : arguments descriptor array.
 //   R2 : arguments array.
-//   R3 : new context containing the current isolate pointer.
+//   R3 : current thread.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
   __ Comment("InvokeDartCodeStub");
 
@@ -799,6 +799,10 @@
   // set up.
   __ LoadPoolPointer(PP);
 
+  // Set up THR, which caches the current thread in Dart code.
+  if (THR != R3) {
+    __ mov(THR, R3);
+  }
   // Load Isolate pointer into temporary register R5.
   __ LoadIsolate(R5, PP);
 
@@ -1604,14 +1608,6 @@
 }
 
 
-void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
-}
-
-
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
@@ -1674,15 +1670,6 @@
 }
 
 
-void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
-}
-
-
 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
 #if defined(DEBUG)
@@ -1973,7 +1960,7 @@
 // R2: frame_pointer.
 // R3: error object.
 // R4: address of stacktrace object.
-// R5: isolate.
+// R5: thread.
 // Does not return.
 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
   ASSERT(kExceptionObjectReg == R0);
@@ -1983,6 +1970,8 @@
   __ mov(FP, R2);  // Frame_pointer.
   __ mov(R0, R3);  // Exception object.
   __ mov(R1, R4);  // StackTrace object.
+  __ mov(THR, R5);
+  __ LoadIsolate(R5, kNoPP);
   // Set the tag.
   __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP);
   __ StoreToOffset(R2, R5, Isolate::vm_tag_offset(), kNoPP);
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index e8b0245..70d03bc 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -41,23 +41,23 @@
 //   EDX : number of arguments to the call.
 // Must preserve callee saved registers EDI and EBX.
 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
-  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t thread_offset = NativeArguments::thread_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
 
   __ EnterFrame(0);
 
-  __ LoadIsolate(ESI);
+  __ LoadIsolate(EDI);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), ESP);
+  __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), EBP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ cmpl(Address(ESI, Isolate::vm_tag_offset()),
+    __ cmpl(Address(EDI, Isolate::vm_tag_offset()),
             Immediate(VMTag::kDartTagId));
     __ j(EQUAL, &ok, Assembler::kNearJump);
     __ Stop("Not coming from Dart code.");
@@ -66,7 +66,7 @@
 #endif
 
   // Mark that the isolate is executing VM code.
-  __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX);
+  __ movl(Address(EDI, Isolate::vm_tag_offset()), ECX);
 
   // Reserve space for arguments and align frame before entering C++ world.
   __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments)));
@@ -75,7 +75,7 @@
   }
 
   // Pass NativeArguments structure by value and call runtime.
-  __ movl(Address(ESP, isolate_offset), ESI);  // Set isolate in NativeArgs.
+  __ movl(Address(ESP, thread_offset), THR);  // Set thread in NativeArgs.
   // There are no runtime calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
   __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
@@ -85,12 +85,12 @@
   __ movl(Address(ESP, retval_offset), EAX);  // Set retval in NativeArguments.
   __ call(ECX);
 
-  // Mark that the isolate is executing Dart code. ESI is callee saved.
-  __ movl(Address(ESI, Isolate::vm_tag_offset()),
+  // Mark that the isolate is executing Dart code. EDI is callee saved.
+  __ movl(Address(EDI, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
 
   // Reset exit frame information in Isolate structure.
-  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0));
+  __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0));
 
   __ LeaveFrame();
   __ ret();
@@ -127,8 +127,8 @@
 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
   const intptr_t native_args_struct_offset =
       NativeEntry::kNumCallWrapperArguments * kWordSize;
-  const intptr_t isolate_offset =
-      NativeArguments::isolate_offset() + native_args_struct_offset;
+  const intptr_t thread_offset =
+      NativeArguments::thread_offset() + native_args_struct_offset;
   const intptr_t argc_tag_offset =
       NativeArguments::argc_tag_offset() + native_args_struct_offset;
   const intptr_t argv_offset =
@@ -138,16 +138,16 @@
 
   __ EnterFrame(0);
 
-  __ LoadIsolate(ESI);
+  __ LoadIsolate(EDI);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to dart VM code.
-  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), ESP);
+  __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), EBP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ cmpl(Address(ESI, Isolate::vm_tag_offset()),
+    __ cmpl(Address(EDI, Isolate::vm_tag_offset()),
             Immediate(VMTag::kDartTagId));
     __ j(EQUAL, &ok, Assembler::kNearJump);
     __ Stop("Not coming from Dart code.");
@@ -156,7 +156,7 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX);
+  __ movl(Address(EDI, Isolate::vm_tag_offset()), ECX);
 
   // Reserve space for the native arguments structure, the outgoing parameters
   // (pointer to the native arguments structure, the C function entry point)
@@ -168,7 +168,7 @@
   }
 
   // Pass NativeArguments structure by value and call native function.
-  __ movl(Address(ESP, isolate_offset), ESI);  // Set isolate in NativeArgs.
+  __ movl(Address(ESP, thread_offset), THR);  // Set thread in NativeArgs.
   __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
   __ movl(Address(ESP, argv_offset), EAX);  // Set argv in NativeArguments.
   __ leal(EAX, Address(EBP, 2 * kWordSize));  // Compute return value addr.
@@ -179,12 +179,12 @@
   __ movl(Address(ESP, kWordSize), ECX);  // Function to call.
   __ call(&NativeEntry::NativeCallWrapperLabel());
 
-  // Mark that the isolate is executing Dart code. ESI is callee saved.
-  __ movl(Address(ESI, Isolate::vm_tag_offset()),
+  // Mark that the isolate is executing Dart code. EDI is callee saved.
+  __ movl(Address(EDI, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
 
   // Reset exit frame information in Isolate structure.
-  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0));
+  __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0));
 
   __ LeaveFrame();
   __ ret();
@@ -200,8 +200,8 @@
 // Uses EDI.
 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
   const intptr_t native_args_struct_offset = kWordSize;
-  const intptr_t isolate_offset =
-      NativeArguments::isolate_offset() + native_args_struct_offset;
+  const intptr_t thread_offset =
+      NativeArguments::thread_offset() + native_args_struct_offset;
   const intptr_t argc_tag_offset =
       NativeArguments::argc_tag_offset() + native_args_struct_offset;
   const intptr_t argv_offset =
@@ -211,16 +211,16 @@
 
   __ EnterFrame(0);
 
-  __ LoadIsolate(ESI);
+  __ LoadIsolate(EDI);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to dart VM code.
-  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), ESP);
+  __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), EBP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ cmpl(Address(ESI, Isolate::vm_tag_offset()),
+    __ cmpl(Address(EDI, Isolate::vm_tag_offset()),
             Immediate(VMTag::kDartTagId));
     __ j(EQUAL, &ok, Assembler::kNearJump);
     __ Stop("Not coming from Dart code.");
@@ -229,7 +229,7 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX);
+  __ movl(Address(EDI, Isolate::vm_tag_offset()), ECX);
 
   // Reserve space for the native arguments structure, the outgoing parameter
   // (pointer to the native arguments structure) and align frame before
@@ -240,7 +240,7 @@
   }
 
   // Pass NativeArguments structure by value and call native function.
-  __ movl(Address(ESP, isolate_offset), ESI);  // Set isolate in NativeArgs.
+  __ movl(Address(ESP, thread_offset), THR);  // Set thread in NativeArgs.
   __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
   __ movl(Address(ESP, argv_offset), EAX);  // Set argv in NativeArguments.
   __ leal(EAX, Address(EBP, 2 * kWordSize));  // Compute return value addr.
@@ -249,12 +249,12 @@
   __ movl(Address(ESP, 0), EAX);  // Pass the pointer to the NativeArguments.
   __ call(ECX);
 
-  // Mark that the isolate is executing Dart code. ESI is callee saved.
-  __ movl(Address(ESI, Isolate::vm_tag_offset()),
+  // Mark that the isolate is executing Dart code. EDI is callee saved.
+  __ movl(Address(EDI, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
 
   // Reset exit frame information in Isolate structure.
-  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0));
+  __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0));
 
   __ LeaveFrame();
   __ ret();
@@ -690,11 +690,13 @@
 //   ESP + 4 : entrypoint of the dart function to call.
 //   ESP + 8 : arguments descriptor array.
 //   ESP + 12 : arguments array.
+//   ESP + 16 : current thread.
 // Uses EAX, EDX, ECX, EDI as temporary registers.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
   const intptr_t kEntryPointOffset = 2 * kWordSize;
   const intptr_t kArgumentsDescOffset = 3 * kWordSize;
   const intptr_t kArgumentsOffset = 4 * kWordSize;
+  const intptr_t kThreadOffset = 5 * kWordSize;
 
   // Save frame pointer coming in.
   __ EnterFrame(0);
@@ -704,27 +706,29 @@
   __ pushl(ESI);
   __ pushl(EDI);
 
-  __ LoadIsolate(ESI);
+  // Set up THR, which caches the current thread in Dart code.
+  __ movl(THR, Address(EBP, kThreadOffset));
+  __ LoadIsolate(EDI);
 
   // Save the current VMTag on the stack.
-  __ movl(ECX, Address(ESI, Isolate::vm_tag_offset()));
+  __ movl(ECX, Address(EDI, Isolate::vm_tag_offset()));
   __ pushl(ECX);
 
   // Mark that the isolate is executing Dart code.
-  __ movl(Address(ESI, Isolate::vm_tag_offset()),
+  __ movl(Address(EDI, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
 
   // Save top resource and top exit frame info. Use EDX as a temporary register.
   // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ movl(EDX, Address(ESI, Isolate::top_resource_offset()));
+  __ movl(EDX, Address(EDI, Isolate::top_resource_offset()));
   __ pushl(EDX);
-  __ movl(Address(ESI, Isolate::top_resource_offset()), Immediate(0));
+  __ movl(Address(EDI, Isolate::top_resource_offset()), Immediate(0));
   // The constant kExitLinkSlotFromEntryFp must be kept in sync with the
   // code below.
   ASSERT(kExitLinkSlotFromEntryFp == -6);
-  __ movl(EDX, Address(ESI, Isolate::top_exit_frame_info_offset()));
+  __ movl(EDX, Address(EDI, Isolate::top_exit_frame_info_offset()));
   __ pushl(EDX);
-  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0));
+  __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0));
 
   // Load arguments descriptor array into EDX.
   __ movl(EDX, Address(EBP, kArgumentsDescOffset));
@@ -767,12 +771,12 @@
 
   // Restore the saved top exit frame info and top resource back into the
   // Isolate structure.
-  __ LoadIsolate(ESI);
-  __ popl(Address(ESI, Isolate::top_exit_frame_info_offset()));
-  __ popl(Address(ESI, Isolate::top_resource_offset()));
+  __ LoadIsolate(EDI);
+  __ popl(Address(EDI, Isolate::top_exit_frame_info_offset()));
+  __ popl(Address(EDI, Isolate::top_resource_offset()));
 
   // Restore the current VMTag from the stack.
-  __ popl(Address(ESI, Isolate::vm_tag_offset()));
+  __ popl(Address(EDI, Isolate::vm_tag_offset()));
 
   // Restore C++ ABI callee-saved registers.
   __ popl(EDI);
@@ -1320,11 +1324,11 @@
     ASSERT((num_args == 1) || (num_args == 2));
     if (num_args == 2) {
       __ movl(EAX, Address(ESP, + 2 * kWordSize));
-      __ UpdateRangeFeedback(EAX, 0, ECX, EBX, EDI, ESI, &not_smi_or_overflow);
+      __ UpdateRangeFeedback(EAX, 0, ECX, EBX, EDI, EDX, &not_smi_or_overflow);
     }
 
     __ movl(EAX, Address(ESP, + 1 * kWordSize));
-    __ UpdateRangeFeedback(EAX, (num_args - 1), ECX, EBX, EDI, ESI,
+    __ UpdateRangeFeedback(EAX, (num_args - 1), ECX, EBX, EDI, EDX,
                            &not_smi_or_overflow);
   }
   if (kind != Token::kILLEGAL) {
@@ -1443,21 +1447,20 @@
   __ movl(EBX, FieldAddress(EAX, Function::instructions_offset()));
   __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
   if (range_collection_mode == kCollectRanges) {
-    __ movl(EDI, Address(ESP, + 1 * kWordSize));
-    if (num_args == 2) {
-      __ movl(ESI, Address(ESP, + 2 * kWordSize));
-    }
     __ EnterStubFrame();
     __ pushl(ECX);
-    if (num_args == 2) {
-      __ pushl(ESI);
+    const intptr_t arg_offset_words = num_args +
+                                      Assembler::kEnterStubFramePushedWords +
+                                      1;  // ECX
+    for (intptr_t i = 0; i < num_args; i++) {
+      __ movl(EDI, Address(ESP, arg_offset_words * kWordSize));
+      __ pushl(EDI);
     }
-    __ pushl(EDI);
     __ call(EBX);
 
     __ movl(ECX, Address(EBP, kFirstLocalSlotFromFp * kWordSize));
     Label done;
-    __ UpdateRangeFeedback(EAX, 2, ECX, EBX, EDI, ESI, &done);
+    __ UpdateRangeFeedback(EAX, 2, ECX, EBX, EDI, EDX, &done);
     __ Bind(&done);
     __ LeaveFrame();
     __ ret();
@@ -1505,15 +1508,6 @@
 }
 
 
-void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
-}
-
-
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
@@ -1592,16 +1586,6 @@
 }
 
 
-void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
-}
-
-
 // Intermediary stub between a static call and its target. ICData contains
 // the target function and the call count.
 // ECX: ICData
@@ -1909,17 +1893,19 @@
 // TOS + 3: frame_pointer
 // TOS + 4: exception object
 // TOS + 5: stacktrace object
-// TOS + 6: isolate
+// TOS + 6: thread
 // No Result.
 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
   ASSERT(kExceptionObjectReg == EAX);
   ASSERT(kStackTraceObjectReg == EDX);
-  __ movl(EDI, Address(ESP, 6 * kWordSize));  // Load target isolate.
+  __ movl(THR, Address(ESP, 6 * kWordSize));  // Load target thread.
   __ movl(kStackTraceObjectReg, Address(ESP, 5 * kWordSize));
   __ movl(kExceptionObjectReg, Address(ESP, 4 * kWordSize));
   __ movl(EBP, Address(ESP, 3 * kWordSize));  // Load target frame_pointer.
   __ movl(EBX, Address(ESP, 1 * kWordSize));  // Load target PC into EBX.
   __ movl(ESP, Address(ESP, 2 * kWordSize));  // Load target stack_pointer.
+  // TODO(koda): Pass thread instead of isolate.
+  __ LoadIsolate(EDI);
   // Set tag.
   __ movl(Address(EDI, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 503a3f1..85a93c5 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -36,7 +36,7 @@
 //   S5 : address of the runtime function to call.
 //   S4 : number of arguments to the call.
 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
-  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t thread_offset = NativeArguments::thread_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
@@ -55,7 +55,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  __ sw(SP, Address(S6, Isolate::top_exit_frame_info_offset()));
+  __ sw(FP, Address(S6, Isolate::top_exit_frame_info_offset()));
 
 #if defined(DEBUG)
   { Label ok;
@@ -78,9 +78,9 @@
   // Pass NativeArguments structure by value and call runtime.
   // Registers A0, A1, A2, and A3 are used.
 
-  ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs.
-  __ mov(A0, S6);
+  ASSERT(thread_offset == 0 * kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(A0, THR);
 
   // There are no runtime calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -146,7 +146,7 @@
 //   A2 : address of first argument in argument array.
 //   A1 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
-  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t thread_offset = NativeArguments::thread_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
@@ -164,7 +164,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ sw(SP, Address(S6, Isolate::top_exit_frame_info_offset()));
+  __ sw(FP, Address(S6, Isolate::top_exit_frame_info_offset()));
 
 #if defined(DEBUG)
   { Label ok;
@@ -182,9 +182,9 @@
   // Initialize NativeArguments structure and call native function.
   // Registers A0, A1, A2, and A3 are used.
 
-  ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs.
-  __ mov(A0, S6);
+  ASSERT(thread_offset == 0 * kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(A0, THR);
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -244,7 +244,7 @@
 //   A2 : address of first argument in argument array.
 //   A1 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
-  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t thread_offset = NativeArguments::thread_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
@@ -262,7 +262,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ sw(SP, Address(S6, Isolate::top_exit_frame_info_offset()));
+  __ sw(FP, Address(S6, Isolate::top_exit_frame_info_offset()));
 
 #if defined(DEBUG)
   { Label ok;
@@ -280,9 +280,9 @@
   // Initialize NativeArguments structure and call native function.
   // Registers A0, A1, A2, and A3 are used.
 
-  ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs.
-  __ mov(A0, S6);
+  ASSERT(thread_offset == 0 * kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(A0, THR);
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -815,6 +815,7 @@
 //   A0 : entrypoint of the Dart function to call.
 //   A1 : arguments descriptor array.
 //   A2 : arguments array.
+//   A3 : current thread.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
   // Save frame pointer coming in.
   __ Comment("InvokeDartCodeStub");
@@ -849,6 +850,10 @@
   // set up.
   __ LoadPoolPointer();
 
+  // Set up THR, which caches the current thread in Dart code.
+  if (THR != A3) {
+    __ mov(THR, A3);
+  }
   __ LoadIsolate(T2);
 
   // Save the current VMTag on the stack.
@@ -1688,14 +1693,6 @@
 }
 
 
-void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, T0);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
-}
-
-
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
@@ -1758,15 +1755,6 @@
 }
 
 
-void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
-}
-
-
 // Intermediary stub between a static call and its target. ICData contains
 // the target function and the call count.
 // S5: ICData
@@ -2087,7 +2075,7 @@
 // A2: frame_pointer.
 // A3: error object.
 // SP + 4*kWordSize: address of stacktrace object.
-// SP + 5*kWordSize: address of isolate.
+// SP + 5*kWordSize: address of thread.
 // Does not return.
 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
   ASSERT(kExceptionObjectReg == V0);
@@ -2097,7 +2085,8 @@
   // the last of five arguments, so it is first pushed on the stack.
   __ lw(V1, Address(SP, 4 * kWordSize));  // StackTrace object.
   __ mov(FP, A2);  // Frame_pointer.
-  __ lw(A3, Address(SP, 5 * kWordSize));  // Isolate.
+  __ lw(THR, Address(SP, 5 * kWordSize));  // Thread.
+  __ LoadIsolate(A3);
   // Set tag.
   __ LoadImmediate(A2, VMTag::kDartTagId);
   __ sw(A2, Address(A3, Isolate::vm_tag_offset()));
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 77da070..6ae08ec 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -38,7 +38,7 @@
 //   R10 : number of arguments to the call.
 // Must preserve callee saved registers R12 and R13.
 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
-  const intptr_t isolate_offset = NativeArguments::isolate_offset();
+  const intptr_t thread_offset = NativeArguments::thread_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
   const intptr_t retval_offset = NativeArguments::retval_offset();
@@ -51,7 +51,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RSP);
+  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RBP);
 
 #if defined(DEBUG)
   { Label ok;
@@ -74,7 +74,7 @@
   }
 
   // Pass NativeArguments structure by value and call runtime.
-  __ movq(Address(RSP, isolate_offset), R12);  // Set isolate in NativeArgs.
+  __ movq(Address(RSP, thread_offset), THR);  // Set thread in NativeArgs.
   // There are no runtime calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
   __ movq(Address(RSP, argc_tag_offset), R10);  // Set argc in NativeArguments.
@@ -131,8 +131,8 @@
 //   R10 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
   const intptr_t native_args_struct_offset = 0;
-  const intptr_t isolate_offset =
-      NativeArguments::isolate_offset() + native_args_struct_offset;
+  const intptr_t thread_offset =
+      NativeArguments::thread_offset() + native_args_struct_offset;
   const intptr_t argc_tag_offset =
       NativeArguments::argc_tag_offset() + native_args_struct_offset;
   const intptr_t argv_offset =
@@ -148,7 +148,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RSP);
+  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RBP);
 
 #if defined(DEBUG)
   { Label ok;
@@ -173,7 +173,7 @@
   }
 
   // Pass NativeArguments structure by value and call native function.
-  __ movq(Address(RSP, isolate_offset), R12);  // Set isolate in NativeArgs.
+  __ movq(Address(RSP, thread_offset), THR);  // Set thread in NativeArgs.
   __ movq(Address(RSP, argc_tag_offset), R10);  // Set argc in NativeArguments.
   __ movq(Address(RSP, argv_offset), RAX);  // Set argv in NativeArguments.
   __ leaq(RAX, Address(RBP, 2 * kWordSize));  // Compute return value addr.
@@ -205,8 +205,8 @@
 //   R10 : argc_tag including number of arguments and function kind.
 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
   const intptr_t native_args_struct_offset = 0;
-  const intptr_t isolate_offset =
-      NativeArguments::isolate_offset() + native_args_struct_offset;
+  const intptr_t thread_offset =
+      NativeArguments::thread_offset() + native_args_struct_offset;
   const intptr_t argc_tag_offset =
       NativeArguments::argc_tag_offset() + native_args_struct_offset;
   const intptr_t argv_offset =
@@ -222,7 +222,7 @@
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RSP);
+  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RBP);
 
 #if defined(DEBUG)
   { Label ok;
@@ -247,7 +247,7 @@
   }
 
   // Pass NativeArguments structure by value and call native function.
-  __ movq(Address(RSP, isolate_offset), R12);  // Set isolate in NativeArgs.
+  __ movq(Address(RSP, thread_offset), THR);  // Set thread in NativeArgs.
   __ movq(Address(RSP, argc_tag_offset), R10);  // Set argc in NativeArguments.
   __ movq(Address(RSP, argv_offset), RAX);  // Set argv in NativeArguments.
   __ leaq(RAX, Address(RBP, 2 * kWordSize));  // Compute return value addr.
@@ -701,7 +701,7 @@
 //   RDI : entrypoint of the Dart function to call.
 //   RSI : arguments descriptor array.
 //   RDX : arguments array.
-//   RCX : new context containing the current isolate pointer.
+//   RCX : current thread.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
   // Save frame pointer coming in.
   __ EnterFrame(0);
@@ -709,6 +709,7 @@
   const Register kEntryPointReg = CallingConventions::kArg1Reg;
   const Register kArgDescReg    = CallingConventions::kArg2Reg;
   const Register kArgsReg       = CallingConventions::kArg3Reg;
+  const Register kThreadReg     = CallingConventions::kArg4Reg;
 
   // At this point, the stack looks like:
   // | saved RBP                                      | <-- RBP
@@ -731,6 +732,10 @@
   // If any additional (or fewer) values are pushed, the offsets in
   // kExitLinkSlotFromEntryFp will need to be changed.
 
+  // Set up THR, which caches the current thread in Dart code.
+  if (THR != kThreadReg) {
+    __ movq(THR, kThreadReg);
+  }
   // Load Isolate pointer into kIsolateReg.
   const Register kIsolateReg = RBX;
   __ LoadIsolate(kIsolateReg);
@@ -1305,9 +1310,9 @@
     // Update counter.
     __ movq(R8, Address(R12, count_offset));
     __ addq(R8, Immediate(Smi::RawValue(1)));
-    __ movq(R9, Immediate(Smi::RawValue(Smi::kMaxValue)));
-    __ cmovnoq(R9, R8);
-    __ StoreIntoSmiField(Address(R12, count_offset), R9);
+    __ movq(R13, Immediate(Smi::RawValue(Smi::kMaxValue)));
+    __ cmovnoq(R13, R8);
+    __ StoreIntoSmiField(Address(R12, count_offset), R13);
   }
 
   __ ret();
@@ -1471,9 +1476,9 @@
     __ Comment("Update caller's counter");
     __ movq(R8, Address(R12, count_offset));
     __ addq(R8, Immediate(Smi::RawValue(1)));
-    __ movq(R9, Immediate(Smi::RawValue(Smi::kMaxValue)));
-    __ cmovnoq(R9, R8);
-    __ StoreIntoSmiField(Address(R12, count_offset), R9);
+    __ movq(R13, Immediate(Smi::RawValue(Smi::kMaxValue)));
+    __ cmovnoq(R13, R8);
+    __ StoreIntoSmiField(Address(R12, count_offset), R13);
   }
 
   __ Comment("Call target");
@@ -1485,12 +1490,12 @@
   if (range_collection_mode == kCollectRanges) {
     __ movq(R8, Address(RSP, + 1 * kWordSize));
     if (num_args == 2) {
-      __ movq(R9, Address(RSP, + 2 * kWordSize));
+      __ movq(R13, Address(RSP, + 2 * kWordSize));
     }
     __ EnterStubFrame();
     __ pushq(RBX);
     if (num_args == 2) {
-      __ pushq(R9);
+      __ pushq(R13);
     }
     __ pushq(R8);
     __ call(RCX);
@@ -1546,15 +1551,6 @@
 }
 
 
-void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
-}
-
-
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
@@ -1633,16 +1629,6 @@
 }
 
 
-void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
-}
-
-
 // Intermediary stub between a static call and its target. ICData contains
 // the target function and the call count.
 // RBX: ICData
@@ -1689,9 +1675,9 @@
     // Increment count for this call.
     __ movq(R8, Address(R12, count_offset));
     __ addq(R8, Immediate(Smi::RawValue(1)));
-    __ movq(R9, Immediate(Smi::RawValue(Smi::kMaxValue)));
-    __ cmovnoq(R9, R8);
-    __ StoreIntoSmiField(Address(R12, count_offset), R9);
+    __ movq(R13, Immediate(Smi::RawValue(Smi::kMaxValue)));
+    __ cmovnoq(R13, R8);
+    __ StoreIntoSmiField(Address(R12, count_offset), R13);
   }
 
   // Load arguments descriptor into R10.
@@ -1956,7 +1942,7 @@
 // Arg3: frame_pointer
 // Arg4: exception object
 // Arg5: stacktrace object
-// Arg6: isolate
+// Arg6: thread
 // No Result.
 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
   ASSERT(kExceptionObjectReg == RAX);
@@ -1967,13 +1953,14 @@
 #if defined(_WIN64)
   Register stacktrace_reg = RBX;
   __ movq(stacktrace_reg, Address(RSP, 5 * kWordSize));
+  __ movq(THR, Address(RSP, 6 * kWordSize));
   Register isolate_reg = RDI;
-  __ movq(isolate_reg, Address(RSP, 6 * kWordSize));
 #else
   Register stacktrace_reg = CallingConventions::kArg5Reg;
+  __ movq(THR, CallingConventions::kArg6Reg);
   Register isolate_reg = CallingConventions::kArg6Reg;
 #endif
-
+  __ LoadIsolate(isolate_reg);
   __ movq(RBP, CallingConventions::kArg3Reg);
   __ movq(RSP, CallingConventions::kArg2Reg);
   __ movq(kStackTraceObjectReg, stacktrace_reg);
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index d578e1f..ee01b1b 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -321,12 +321,12 @@
   V(DartNativeWrappersLibName, "dart.nativewrappers")                          \
   V(DartCore, "dart:core")                                                     \
   V(DartCollection, "dart:collection")                                         \
+  V(DartDeveloper, "dart:developer")                                           \
   V(DartInternal, "dart:_internal")                                            \
   V(DartIsolate, "dart:isolate")                                               \
   V(DartMirrors, "dart:mirrors")                                               \
   V(DartTypedData, "dart:typed_data")                                          \
   V(DartVMService, "dart:vmservice")                                           \
-  V(DartProfiler, "dart:profiler")                                             \
   V(DartIOLibName, "dart.io")                                                  \
   V(EvalSourceUri, "evaluate:source")                                          \
   V(_Random, "_Random")                                                        \
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 056430c..457f1a4 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -56,6 +56,9 @@
 
   // The isolate that this thread is operating on, or NULL if none.
   Isolate* isolate() const { return isolate_; }
+  static intptr_t isolate_offset() {
+    return OFFSET_OF(Thread, isolate_);
+  }
 
   // The (topmost) CHA for the compilation in the isolate of this thread.
   // TODO(23153): Move this out of Isolate/Thread.
diff --git a/runtime/vm/token.h b/runtime/vm/token.h
index d22a6c0..a1018f8 100644
--- a/runtime/vm/token.h
+++ b/runtime/vm/token.h
@@ -11,18 +11,19 @@
 
 //  Operator precedence table
 //
-//  13  multiplicative  * / ~/ %
-//  12  additive        + -
-//  11  shift           << >>
-//  10  bitwise and     &
-//   9  bitwise xor     ^
-//   8  bitwise or      |
-//   7  relational      >= > <= < is as
-//   6  equality        == != === !==
-//   5  logical and     &&
-//   4  logical or      ||
+//  14  multiplicative  * / ~/ %
+//  13  additive        + -
+//  12  shift           << >>
+//  11  bitwise and     &
+//  10  bitwise xor     ^
+//   9  bitwise or      |
+//   8  relational      >= > <= < is as
+//   7  equality        == != === !==
+//   6  logical and     &&
+//   5  logical or      ||
+//   4  null check      ??
 //   3  conditional     ?
-//   2  assignment      = *= /= ~/= %= += -= <<= >>= &= ^= |=
+//   2  assignment      = *= /= ~/= %= += -= <<= >>= &= ^= |= ??=
 //   1  comma           ,
 
 
@@ -43,6 +44,7 @@
   TOK(kCOLON,  ":", 0, kNoAttribute)                                           \
   TOK(kSEMICOLON, ";", 0, kNoAttribute)                                        \
   TOK(kPERIOD, ".", 0, kNoAttribute)                                           \
+  TOK(kQM_PERIOD, "?.", 0, kNoAttribute)                                       \
   TOK(kINCR,   "++", 0, kNoAttribute)                                          \
   TOK(kDECR,   "--", 0, kNoAttribute)                                          \
                                                                                \
@@ -61,52 +63,55 @@
   TOK(kASSIGN_TRUNCDIV, "~/=", 2, kNoAttribute)                                \
   TOK(kASSIGN_DIV, "/=", 2, kNoAttribute)                                      \
   TOK(kASSIGN_MOD, "%=", 2, kNoAttribute)                                      \
+  /* Avoid trigraph ??= below. */                                              \
+  TOK(kASSIGN_COND, "?\?=", 2, kNoAttribute)                                   \
                                                                                \
   TOK(kCASCADE, "..", 2, kNoAttribute)                                         \
                                                                                \
   TOK(kCOMMA, ",", 1, kNoAttribute)                                            \
-  TOK(kOR, "||", 4, kNoAttribute)                                              \
-  TOK(kAND, "&&", 5, kNoAttribute)                                             \
-  TOK(kBIT_OR, "|", 8, kNoAttribute)                                           \
-  TOK(kBIT_XOR, "^", 9, kNoAttribute)                                          \
-  TOK(kBIT_AND, "&", 10, kNoAttribute)                                         \
+  TOK(kOR, "||", 5, kNoAttribute)                                              \
+  TOK(kAND, "&&", 6, kNoAttribute)                                             \
+  TOK(kBIT_OR, "|", 9, kNoAttribute)                                           \
+  TOK(kBIT_XOR, "^", 10, kNoAttribute)                                         \
+  TOK(kBIT_AND, "&", 11, kNoAttribute)                                         \
   TOK(kBIT_NOT, "~", 0, kNoAttribute)                                          \
                                                                                \
   /* Shift operators. */                                                       \
-  TOK(kSHL, "<<", 11, kNoAttribute)                                            \
-  TOK(kSHR, ">>", 11, kNoAttribute)                                            \
+  TOK(kSHL, "<<", 12, kNoAttribute)                                            \
+  TOK(kSHR, ">>", 12, kNoAttribute)                                            \
                                                                                \
   /* Additive operators. */                                                    \
-  TOK(kADD, "+", 12, kNoAttribute)                                             \
-  TOK(kSUB, "-", 12, kNoAttribute)                                             \
+  TOK(kADD, "+", 13, kNoAttribute)                                             \
+  TOK(kSUB, "-", 13, kNoAttribute)                                             \
                                                                                \
   /* Multiplicative operators */                                               \
-  TOK(kMUL, "*", 13, kNoAttribute)                                             \
-  TOK(kDIV, "/", 13, kNoAttribute)                                             \
-  TOK(kTRUNCDIV, "~/", 13, kNoAttribute)                                       \
-  TOK(kMOD, "%", 13, kNoAttribute)                                             \
+  TOK(kMUL, "*", 14, kNoAttribute)                                             \
+  TOK(kDIV, "/", 14, kNoAttribute)                                             \
+  TOK(kTRUNCDIV, "~/", 14, kNoAttribute)                                       \
+  TOK(kMOD, "%", 14, kNoAttribute)                                             \
                                                                                \
   TOK(kNOT, "!", 0, kNoAttribute)                                              \
   TOK(kCONDITIONAL, "?", 3, kNoAttribute)                                      \
+  TOK(kIFNULL, "??", 4, kNoAttribute)                                          \
                                                                                \
   /* Equality operators.                             */                        \
   /* Please update IsEqualityOperator() if you make  */                        \
   /* any changes to this block.                      */                        \
-  TOK(kEQ, "==", 6, kNoAttribute)                                              \
-  TOK(kNE, "!=", 6, kNoAttribute)                                              \
-  TOK(kEQ_STRICT, "===", 6, kNoAttribute)                                      \
-  TOK(kNE_STRICT, "!==", 6, kNoAttribute)                                      \
+  TOK(kEQ, "==", 7, kNoAttribute)                                              \
+  TOK(kNE, "!=", 7, kNoAttribute)                                              \
+  TOK(kEQ_STRICT, "===", 7, kNoAttribute)                                      \
+  TOK(kNE_STRICT, "!==", 7, kNoAttribute)                                      \
                                                                                \
   /* Relational operators.                             */                      \
   /* Please update IsRelationalOperator() if you make  */                      \
   /* any changes to this block.                        */                      \
-  TOK(kLT, "<", 7, kNoAttribute)                                               \
-  TOK(kGT, ">", 7, kNoAttribute)                                               \
-  TOK(kLTE, "<=", 7, kNoAttribute)                                             \
-  TOK(kGTE, ">=", 7, kNoAttribute)                                             \
+  TOK(kLT, "<", 8, kNoAttribute)                                               \
+  TOK(kGT, ">", 8, kNoAttribute)                                               \
+  TOK(kLTE, "<=", 8, kNoAttribute)                                             \
+  TOK(kGTE, ">=", 8, kNoAttribute)                                             \
                                                                                \
   /* Internal token for !(expr is Type) negative type test operator */         \
-  TOK(kISNOT, "", 10, kNoAttribute)                                            \
+  TOK(kISNOT, "", 11, kNoAttribute)                                            \
                                                                                \
   TOK(kINDEX, "[]", 0, kNoAttribute)                                           \
   TOK(kASSIGN_INDEX, "[]=", 0, kNoAttribute)                                   \
@@ -141,8 +146,8 @@
 // to update kFirstKeyword and kLastKeyword below.
 #define DART_KEYWORD_LIST(KW)                                                  \
   KW(kABSTRACT, "abstract", 0, kPseudoKeyword) /* == kFirstKeyword */          \
-  KW(kAS, "as", 10, kPseudoKeyword)                                            \
-  KW(kASSERT, "assert", 10, kKeyword)                                          \
+  KW(kAS, "as", 11, kPseudoKeyword)                                            \
+  KW(kASSERT, "assert", 11, kKeyword)                                          \
   KW(kBREAK, "break", 0, kKeyword)                                             \
   KW(kCASE, "case", 0, kKeyword)                                               \
   KW(kCATCH, "catch", 0, kKeyword)                                             \
@@ -166,7 +171,7 @@
   KW(kIMPLEMENTS, "implements", 0, kPseudoKeyword)                             \
   KW(kIMPORT, "import", 0, kPseudoKeyword)                                     \
   KW(kIN, "in", 0, kKeyword)                                                   \
-  KW(kIS, "is", 10, kKeyword)                                                  \
+  KW(kIS, "is", 11, kKeyword)                                                  \
   KW(kLIBRARY, "library", 0, kPseudoKeyword)                                   \
   KW(kNEW, "new", 0, kKeyword)                                                 \
   KW(kNULL, "null", 0, kKeyword)                                               \
@@ -212,7 +217,7 @@
   static const int kNumKeywords = kLastKeyword - kFirstKeyword + 1;
 
   static bool IsAssignmentOperator(Kind tok) {
-    return kASSIGN <= tok && tok <= kASSIGN_MOD;
+    return kASSIGN <= tok && tok <= kASSIGN_COND;
   }
 
   static bool IsRelationalOperator(Kind tok) {
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index 211950f..e298592 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -26,7 +26,6 @@
     'mirrors_cc_file': '<(gen_source_dir)/mirrors_gen.cc',
     'mirrors_patch_cc_file': '<(gen_source_dir)/mirrors_patch_gen.cc',
     'profiler_cc_file': '<(gen_source_dir)/profiler_gen.cc',
-    'profiler_patch_cc_file': '<(gen_source_dir)/profiler_patch_gen.cc',
     'service_cc_file': '<(gen_source_dir)/service_gen.cc',
     'snapshot_test_dat_file': '<(gen_source_dir)/snapshot_test.dat',
     'snapshot_test_in_dat_file': 'snapshot_test_in.dat',
@@ -196,7 +195,6 @@
         'generate_mirrors_cc_file#host',
         'generate_mirrors_patch_cc_file#host',
         'generate_profiler_cc_file#host',
-        'generate_profiler_patch_cc_file#host',
         'generate_typed_data_cc_file#host',
         'generate_typed_data_patch_cc_file#host',
       ],
@@ -209,7 +207,6 @@
         '../lib/isolate_sources.gypi',
         '../lib/math_sources.gypi',
         '../lib/mirrors_sources.gypi',
-        '../lib/profiler_sources.gypi',
         '../lib/typed_data_sources.gypi',
       ],
       'sources': [
@@ -234,7 +231,6 @@
         '<(mirrors_cc_file)',
         '<(mirrors_patch_cc_file)',
         '<(profiler_cc_file)',
-        '<(profiler_patch_cc_file)',
         '<(typed_data_cc_file)',
         '<(typed_data_patch_cc_file)',
       ],
@@ -255,7 +251,6 @@
         '../lib/isolate_sources.gypi',
         '../lib/math_sources.gypi',
         '../lib/mirrors_sources.gypi',
-        '../lib/profiler_sources.gypi',
         '../lib/typed_data_sources.gypi',
       ],
       'sources': [
@@ -1025,46 +1020,6 @@
       ]
     },
     {
-      'target_name': 'generate_profiler_patch_cc_file',
-      'type': 'none',
-      'toolsets':['host'],
-      'includes': [
-        # Load the runtime implementation sources.
-        '../lib/profiler_sources.gypi',
-      ],
-      'sources/': [
-        # Exclude all .[cc|h] files.
-        # This is only here for reference. Excludes happen after
-        # variable expansion, so the script has to do its own
-        # exclude processing of the sources being passed.
-        ['exclude', '\\.cc|h$'],
-      ],
-      'actions': [
-        {
-          'action_name': 'generate_profiler_patch_cc',
-          'inputs': [
-            '../tools/gen_library_src_paths.py',
-            '<(libgen_in_cc_file)',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(profiler_patch_cc_file)',
-          ],
-          'action': [
-            'python',
-            'tools/gen_library_src_paths.py',
-            '--output', '<(profiler_patch_cc_file)',
-            '--input_cc', '<(libgen_in_cc_file)',
-            '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::profiler_patch_paths_',
-            '--library_name', 'dart:profiler',
-            '<@(_sources)',
-          ],
-          'message': 'Generating ''<(profiler_patch_cc_file)'' file.'
-        },
-      ]
-    },
-    {
       'target_name': 'generate_developer_cc_file',
       'type': 'none',
       'toolsets':['host'],
diff --git a/samples/samples.status b/samples/samples.status
index bdf327c..d0d70d65 100644
--- a/samples/samples.status
+++ b/samples/samples.status
@@ -25,4 +25,4 @@
 *: Skip
 
 [ $compiler == dart2js && $cps_ir ]
-sample_extension/test/sample_extension_test: Crash # unsupported element kind: context:field
+sample_extension/test/sample_extension_test: Crash #  Unhandled node
diff --git a/sdk/lib/_internal/compiler/js_lib/core_patch.dart b/sdk/lib/_internal/compiler/js_lib/core_patch.dart
index ce675bf..d42f9a85 100644
--- a/sdk/lib/_internal/compiler/js_lib/core_patch.dart
+++ b/sdk/lib/_internal/compiler/js_lib/core_patch.dart
@@ -42,7 +42,7 @@
 
 
   @patch
-  String toString() => Primitives.objectToString(this);
+  String toString() => Primitives.objectToHumanReadableString(this);
 
   @patch
   dynamic noSuchMethod(Invocation invocation) {
@@ -154,7 +154,7 @@
   static String _objectToString(Object object) {
     // Closures all have useful and safe toString methods.
     if (object is Closure) return object.toString();
-    return Primitives.objectToString(object);
+    return Primitives.objectToHumanReadableString(object);
   }
 
   @patch
diff --git a/sdk/lib/_internal/compiler/js_lib/foreign_helper.dart b/sdk/lib/_internal/compiler/js_lib/foreign_helper.dart
index e5e7f6f..cec0b8d 100644
--- a/sdk/lib/_internal/compiler/js_lib/foreign_helper.dart
+++ b/sdk/lib/_internal/compiler/js_lib/foreign_helper.dart
@@ -202,12 +202,6 @@
  */
 String JS_OPERATOR_AS_PREFIX() {}
 
-/// Returns the name of the class `Object` in the generated code.
-String JS_OBJECT_CLASS_NAME() {}
-
-/// Returns the name of the class `Null` in the generated code.
-String JS_NULL_CLASS_NAME() {}
-
 /**
  * Returns the field name used for determining if an object or its
  * interceptor has JavaScript indexing behavior.
diff --git a/sdk/lib/_internal/compiler/js_lib/interceptors.dart b/sdk/lib/_internal/compiler/js_lib/interceptors.dart
index 5ec9e93..200f2b9 100644
--- a/sdk/lib/_internal/compiler/js_lib/interceptors.dart
+++ b/sdk/lib/_internal/compiler/js_lib/interceptors.dart
@@ -290,7 +290,7 @@
 
   int get hashCode => Primitives.objectHashCode(this);
 
-  String toString() => Primitives.objectToString(this);
+  String toString() => Primitives.objectToHumanReadableString(this);
 
   dynamic noSuchMethod(Invocation invocation) {
     throw new NoSuchMethodError(
diff --git a/sdk/lib/_internal/compiler/js_lib/js_helper.dart b/sdk/lib/_internal/compiler/js_lib/js_helper.dart
index 448bfe6..470b0da 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_helper.dart
@@ -57,8 +57,6 @@
     JS_GET_NAME,
     JS_HAS_EQUALS,
     JS_IS_INDEXABLE_FIELD_NAME,
-    JS_NULL_CLASS_NAME,
-    JS_OBJECT_CLASS_NAME,
     JS_OPERATOR_AS_PREFIX,
     JS_SIGNATURE_NAME,
     JS_STRING_CONCAT,
@@ -89,12 +87,12 @@
 abstract class InternalMap {
 }
 
-/// Extracts the classname from the isCheckProperty.
+/// Extracts the JavaScript-constructor name from the given isCheckProperty.
 // TODO(floitsch): move this to foreign_helper.dart or similar.
 @ForceInline()
-String classNameFromIsCheckProperty(String isCheckProperty) {
+String isCheckPropertyToJsConstructorName(String isCheckProperty) {
   return JS_BUILTIN('returns:String;depends:none;effects:none',
-                    JsBuiltin.classNameFromIsCheckProperty,
+                    JsBuiltin.isCheckPropertyToJsConstructorName,
                     isCheckProperty);
 }
 
@@ -110,25 +108,24 @@
 /// Creates a function type object.
 // TODO(floitsch): move this to foreign_helper.dart or similar.
 @ForceInline()
-createDartFunctionType() {
+createDartFunctionTypeRti() {
   return JS_BUILTIN('returns:=Object;effects:none;depends:none',
-                    JsBuiltin.createFunctionType);
-}
-
-/// Returns true if the given [type] is _the_ `Function` type.
-// TODO(floitsch): move this to foreign_helper.dart or similar.
-@ForceInline()
-bool isDartFunctionTypeLiteral(Object type) {
-  return JS_BUILTIN('returns:bool;effects:none;depends:none',
-                    JsBuiltin.isFunctionTypeLiteral, type);
+                    JsBuiltin.createFunctionTypeRti);
 }
 
 /// Retrieves the class name from type information stored on the constructor of
 /// [type].
 // TODO(floitsch): move this to foreign_helper.dart or similar.
 @ForceInline()
-String getDartTypeName(Object type) {
-  return JS_BUILTIN('String', JsBuiltin.typeName, type);
+String rawRtiToJsConstructorName(Object rti) {
+  return JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, rti);
+}
+
+/// Returns the rti from the given [constructorName].
+// TODO(floitsch): make this a builtin.
+jsConstructorNameToRti(String constructorName) {
+  var getTypeFromName = JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME);
+  return JS('', '#(#)', getTypeFromName, constructorName);
 }
 
 /// Returns the raw runtime type of the given object [o].
@@ -147,12 +144,38 @@
 ///
 /// The argument [other] is the name of the other type, as computed by
 /// [runtimeTypeToString].
+@ForceInline()
 bool builtinIsSubtype(type, String other) {
   return JS_BUILTIN('returns:bool;effects:none;depends:none',
                     JsBuiltin.isSubtype, other, type);
 }
 
+/// Returns true if the given [type] is _the_ `Function` type.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@ForceInline()
+bool isDartFunctionTypeRti(Object type) {
+  return JS_BUILTIN('returns:bool;effects:none;depends:none',
+                    JsBuiltin.isFunctionTypeRti, type);
+}
+
+/// Returns whether the given type is _the_ Dart Object type.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@ForceInline()
+bool isDartObjectTypeRti(type) {
+  return JS_BUILTIN('returns:bool;effects:none;depends:none',
+                    JsBuiltin.isDartObjectTypeRti, type);
+}
+
+/// Returns whether the given type is _the_ null type.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@ForceInline()
+bool isNullTypeRti(type) {
+  return JS_BUILTIN('returns:bool;effects:none;depends:none',
+                    JsBuiltin.isNullTypeRti, type);
+}
+
 /// Returns the metadata of the given [index].
+// TODO(floitsch): move this to foreign_helper.dart or similar.
 @ForceInline()
 getMetadata(int index) {
   return JS_BUILTIN('returns:var;effects:none;depends:none',
@@ -160,6 +183,7 @@
 }
 
 /// Returns the type of the given [index].
+// TODO(floitsch): move this to foreign_helper.dart or similar.
 @ForceInline()
 getType(int index) {
   return JS_BUILTIN('returns:var;effects:none;depends:none',
@@ -776,6 +800,9 @@
   /// with the given type arguments.
   ///
   /// In minified mode, uses the unminified names if available.
+  ///
+  /// The given [className] string generally contains the name of the JavaScript
+  /// constructor of the given class.
   static String formatType(String className, List typeArguments) {
     return unmangleAllIdentifiersIfPreservedAnyways
         ('$className${joinArguments(typeArguments, 0)}');
@@ -806,7 +833,7 @@
   }
 
   /// In minified mode, uses the unminified names if available.
-  static String objectToString(Object object) {
+  static String objectToHumanReadableString(Object object) {
     String name = objectTypeName(object);
     return "Instance of '$name'";
   }
@@ -1330,10 +1357,6 @@
     return JS('', '#.apply(#, #)', jsFunction, function, positionalArguments);
   }
 
-  static _mangledNameMatchesType(String mangledName, TypeImpl type) {
-    return JS('bool', '# == #', mangledName, type._typeName);
-  }
-
   static bool identicalImplementation(a, b) {
     return JS('bool', '# == null', a)
       ? JS('bool', '# == null', b)
@@ -1957,29 +1980,17 @@
     var match;
     // Using JS to give type hints to the compiler to help tree-shaking.
     // TODO(ahe): That should be unnecessary due to type inference.
-    var nsme =
-        JS('TypeErrorDecoder', '#', TypeErrorDecoder.noSuchMethodPattern);
-    var notClosure =
-        JS('TypeErrorDecoder', '#', TypeErrorDecoder.notClosurePattern);
-    var nullCall =
-        JS('TypeErrorDecoder', '#', TypeErrorDecoder.nullCallPattern);
-    var nullLiteralCall =
-        JS('TypeErrorDecoder', '#', TypeErrorDecoder.nullLiteralCallPattern);
-    var undefCall =
-        JS('TypeErrorDecoder', '#', TypeErrorDecoder.undefinedCallPattern);
-    var undefLiteralCall =
-        JS('TypeErrorDecoder', '#',
-           TypeErrorDecoder.undefinedLiteralCallPattern);
-    var nullProperty =
-        JS('TypeErrorDecoder', '#', TypeErrorDecoder.nullPropertyPattern);
-    var nullLiteralProperty =
-        JS('TypeErrorDecoder', '#',
-           TypeErrorDecoder.nullLiteralPropertyPattern);
-    var undefProperty =
-        JS('TypeErrorDecoder', '#', TypeErrorDecoder.undefinedPropertyPattern);
+    var nsme = TypeErrorDecoder.noSuchMethodPattern;
+    var notClosure = TypeErrorDecoder.notClosurePattern;
+    var nullCall = TypeErrorDecoder.nullCallPattern;
+    var nullLiteralCall = TypeErrorDecoder.nullLiteralCallPattern;
+    var undefCall = TypeErrorDecoder.undefinedCallPattern;
+    var undefLiteralCall = TypeErrorDecoder.undefinedLiteralCallPattern;
+    var nullProperty = TypeErrorDecoder.nullPropertyPattern;
+    var nullLiteralProperty = TypeErrorDecoder.nullLiteralPropertyPattern;
+    var undefProperty = TypeErrorDecoder.undefinedPropertyPattern;
     var undefLiteralProperty =
-        JS('TypeErrorDecoder', '#',
-           TypeErrorDecoder.undefinedLiteralPropertyPattern);
+        TypeErrorDecoder.undefinedLiteralPropertyPattern;
     if ((match = nsme.matchTypeError(message)) != null) {
       return saveStackTrace(new JsNoSuchMethodError(message, match));
     } else if ((match = notClosure.matchTypeError(message)) != null) {
@@ -2201,6 +2212,9 @@
     String callName = JS('String|Null', '#[#]', function,
         JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY));
 
+    // This variable holds either an index into the types-table, or a function
+    // that can compute a function-rti. (The latter is necessary if the type
+    // is dependent on generic arguments).
     var functionType;
     if (reflectionInfo is List) {
       JS('', '#.\$reflectionInfo = #', function, reflectionInfo);
@@ -2635,7 +2649,7 @@
 
   toString() {
     var receiver = _receiver == null ? _self : _receiver;
-    return "Closure '$_name' of ${Primitives.objectToString(receiver)}";
+    return "Closure '$_name' of ${Primitives.objectToHumanReadableString(receiver)}";
   }
 
   @NoInline()
@@ -2853,7 +2867,7 @@
 }
 
 void propertyTypeError(value, property) {
-  String name = classNameFromIsCheckProperty(property);
+  String name = isCheckPropertyToJsConstructorName(property);
   throw new TypeErrorImplementation(value, name);
 }
 
@@ -3213,7 +3227,7 @@
   }
 
   toRti() {
-    var result = createDartFunctionType();
+    var result = createDartFunctionTypeRti();
     if (isVoid) {
       JS('', '#[#] = true', result, JS_FUNCTION_TYPE_VOID_RETURN_TAG());
     } else {
@@ -3319,11 +3333,11 @@
 }
 
 RuntimeType buildInterfaceType(rti, typeArguments) {
-  String name = JS('String', r'#.name', rti);
+  String jsConstructorName = rawRtiToJsConstructorName(rti);
   if (typeArguments == null || typeArguments.isEmpty) {
-    return new RuntimeTypePlain(name);
+    return new RuntimeTypePlain(jsConstructorName);
   }
-  return new RuntimeTypeGeneric(name, typeArguments, null);
+  return new RuntimeTypeGeneric(jsConstructorName, typeArguments, null);
 }
 
 class DynamicRuntimeType extends RuntimeType {
@@ -3395,41 +3409,41 @@
 }
 
 class RuntimeTypePlain extends RuntimeType {
-  final String name;
+  /// The constructor name of this raw type.
+  final String _jsConstructorName;
 
-  RuntimeTypePlain(this.name);
+  RuntimeTypePlain(this._jsConstructorName);
 
   toRti() {
-    var getTypeFromName = JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME);
-    var rti = JS('', '#(#)', getTypeFromName, name);
-    if (rti == null) throw "no type for '$name'";
+    var rti = jsConstructorNameToRti(_jsConstructorName);
+    if (rti == null) throw "no type for '$_jsConstructorName'";
     return rti;
   }
 
-  String toString() => name;
+  String toString() => _jsConstructorName;
 }
 
 class RuntimeTypeGeneric extends RuntimeType {
-  final String name;
+  /// The constructor name of the raw type for this generic type.
+  final String _jsConstructorName;
   final List<RuntimeType> arguments;
   var rti;
 
-  RuntimeTypeGeneric(this.name, this.arguments, this.rti);
+  RuntimeTypeGeneric(this._jsConstructorName, this.arguments, this.rti);
 
   toRti() {
     if (rti != null) return rti;
-    var getTypeFromName = JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME);
-    var result = JS('JSExtendableArray', '[#(#)]', getTypeFromName, name);
+    var result = [jsConstructorNameToRti(_jsConstructorName)];
     if (result[0] == null) {
-      throw "no type for '$name<...>'";
+      throw "no type for '$_jsConstructorName<...>'";
     }
     for (RuntimeType argument in arguments) {
-      JS('', '#.push(#)', result, argument.toRti());
+      result.add(argument.toRti());
     }
     return rti = result;
   }
 
-  String toString() => '$name<${arguments.join(", ")}>';
+  String toString() => '$_jsConstructorName<${arguments.join(", ")}>';
 }
 
 class FunctionTypeInfoDecoderRing {
@@ -3460,6 +3474,7 @@
   String _convert(type) {
     String result = runtimeTypeToString(type);
     if (result != null) return result;
+    // Currently the [runtimeTypeToString] method doesn't handle function rtis.
     if (JS('bool', '"func" in #', type)) {
       return new FunctionTypeInfoDecoderRing(type).toString();
     } else {
diff --git a/sdk/lib/_internal/compiler/js_lib/js_rti.dart b/sdk/lib/_internal/compiler/js_lib/js_rti.dart
index ec6ae53..7b9db7c 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_rti.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_rti.dart
@@ -51,7 +51,8 @@
 
   String toString() {
     if (_unmangledName != null) return _unmangledName;
-    String unmangledName = unmangleAllIdentifiersIfPreservedAnyways(_typeName);
+    String unmangledName =
+        unmangleAllIdentifiersIfPreservedAnyways(_typeName);
     return _unmangledName = unmangledName;
   }
 
@@ -80,14 +81,14 @@
 getMangledTypeName(TypeImpl type) => type._typeName;
 
 /**
- * Sets the runtime type information on [target]. [typeInfo] is a type
+ * Sets the runtime type information on [target]. [rti] is a type
  * representation of type 4 or 5, that is, either a JavaScript array or
  * `null`.
  */
-Object setRuntimeTypeInfo(Object target, var typeInfo) {
-  assert(typeInfo == null || isJsArray(typeInfo));
+Object setRuntimeTypeInfo(Object target, var rti) {
+  assert(rti == null || isJsArray(rti));
   // We have to check for null because factories may return null.
-  if (target != null) JS('var', r'#.$builtinTypeInfo = #', target, typeInfo);
+  if (target != null) JS('var', r'#.$builtinTypeInfo = #', target, rti);
   return target;
 }
 
@@ -134,38 +135,37 @@
  * of [object].
  */
 String getClassName(var object) {
-  return getDartTypeName(getRawRuntimeType(getInterceptor(object)));
+  return rawRtiToJsConstructorName(getRawRuntimeType(getInterceptor(object)));
 }
 
 /**
- * Creates the string representation for the type representation [runtimeType]
+ * Creates the string representation for the type representation [rti]
  * of type 4, the JavaScript array, where the first element represents the class
  * and the remaining elements represent the type arguments.
  */
-String getRuntimeTypeAsString(var runtimeType, {String onTypeVariable(int i)}) {
-  assert(isJsArray(runtimeType));
-  String className = getDartTypeName(getIndex(runtimeType, 0));
-  return '$className'
-         '${joinArguments(runtimeType, 1, onTypeVariable: onTypeVariable)}';
+String getRuntimeTypeAsString(var rti, {String onTypeVariable(int i)}) {
+  assert(isJsArray(rti));
+  String className = rawRtiToJsConstructorName(getIndex(rti, 0));
+  return '$className${joinArguments(rti, 1, onTypeVariable: onTypeVariable)}';
 }
 
 /**
- * Returns a human-readable representation of the type representation [type].
+ * Returns a human-readable representation of the type representation [rti].
  */
-String runtimeTypeToString(var type, {String onTypeVariable(int i)}) {
-  if (type == null) {
+String runtimeTypeToString(var rti, {String onTypeVariable(int i)}) {
+  if (rti == null) {
     return 'dynamic';
-  } else if (isJsArray(type)) {
+  } else if (isJsArray(rti)) {
     // A list representing a type with arguments.
-    return getRuntimeTypeAsString(type, onTypeVariable: onTypeVariable);
-  } else if (isJsFunction(type)) {
+    return getRuntimeTypeAsString(rti, onTypeVariable: onTypeVariable);
+  } else if (isJsFunction(rti)) {
     // A reference to the constructor.
-    return getDartTypeName(type);
-  } else if (type is int) {
+    return rawRtiToJsConstructorName(rti);
+  } else if (rti is int) {
     if (onTypeVariable == null) {
-      return type.toString();
+      return rti.toString();
     } else {
-      return onTypeVariable(type);
+      return onTypeVariable(rti);
     }
   } else {
     // TODO(ahe): Handle function types, and be sure to always return a string.
@@ -208,8 +208,8 @@
 String getRuntimeTypeString(var object) {
   String className = getClassName(object);
   if (object == null) return className;
-  var typeInfo = JS('var', r'#.$builtinTypeInfo', object);
-  return "$className${joinArguments(typeInfo, 0)}";
+  var rti = JS('var', r'#.$builtinTypeInfo', object);
+  return "$className${joinArguments(rti, 0)}";
 }
 
 Type getRuntimeType(var object) {
@@ -273,7 +273,7 @@
 String computeTypeName(String isField, List arguments) {
   // Extract the class name from the is field and append the textual
   // representation of the type arguments.
-  return Primitives.formatType(classNameFromIsCheckProperty(isField),
+  return Primitives.formatType(isCheckPropertyToJsConstructorName(isField),
                                arguments);
 }
 
@@ -364,8 +364,7 @@
  */
 bool isSupertypeOfNull(var type) {
   // `null` means `dynamic`.
-  return type == null || getDartTypeName(type) == JS_OBJECT_CLASS_NAME()
-                      || getDartTypeName(type) == JS_NULL_CLASS_NAME();
+  return type == null || isDartObjectTypeRti(type) || isNullTypeRti(type);
 }
 
 /**
@@ -444,7 +443,7 @@
   }
   // Check function types against the Function class.
   if (isDartFunctionType(s)) {
-    return isDartFunctionTypeLiteral(t);
+    return isDartFunctionTypeRti(t);
   }
 
   // Get the object describing the class and check for the subtyping flag
diff --git a/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart b/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart
index 0e45562..03fcf72 100644
--- a/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart
@@ -104,16 +104,16 @@
   ///       ...
   dartObjectConstructor,
 
-  /// Returns the class name given an [isCheckProperty].
+  /// Returns the JavaScript-constructor name given an [isCheckProperty].
   ///
   /// This relies on a deterministic encoding of is-check properties (for
   /// example `$isFoo` for a class `Foo`). In minified code the returned
   /// classname is the minified name of the class.
   ///
   ///     JS_BUILTIN('returns:String;depends:none;effects:none',
-  ///                JsBuiltin.classNameFromIsCheckProperty,
+  ///                JsBuiltin.isCheckPropertyToJsConstructorName,
   ///                isCheckProperty);
-  classNameFromIsCheckProperty,
+  isCheckPropertyToJsConstructorName,
 
   /// Returns true if the given type is a function type. Returns false for
   /// the one `Function` type singleton. (See [isFunctionTypeSingleton]).
@@ -121,21 +121,15 @@
   ///     JS_BUILTIN('bool', JsBuiltin.isFunctionType, o)
   isFunctionType,
 
-  /// Returns true if the given type is the `Function` type literal.
-  ///
-  ///     JS_BUILTIN('returns:bool;effects:none;depends:none',
-  ///                JsBuiltin.isFunctionTypeLiteral, type);
-  isFunctionTypeLiteral,
-
   /// Returns a new function type object.
   ///
   ///     JS_BUILTIN('=Object', JsBuiltin.createFunctionType)
-  createFunctionType,
+  createFunctionTypeRti,
 
-  /// Returns the class name of the given type.
+  /// Returns the JavaScript-constructor name given an rti encoding.
   ///
-  ///     JS_BUILTIN('String', JsBuiltin.typeName, type)
-  typeName,
+  ///     JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, rti)
+  rawRtiToJsConstructorName,
 
   /// Returns the raw runtime type of the given object. The given argument
   /// [o] should be the interceptor (for non-Dart objects).
@@ -154,6 +148,26 @@
   ///                JsBuiltin.isSubtype, other, type);
   isSubtype,
 
+  /// Returns true if the given type is _the_ `Function` type.
+  /// That is, it returns true if the given [type] is exactly the `Function`
+  /// type rti-encoding.
+  ///
+  ///     JS_BUILTIN('returns:bool;effects:none;depends:none',
+  ///                JsBuiltin.isFunctionTypeLiteral, type);
+  isFunctionTypeRti,
+
+  /// Returns whether the given type is _the_ null-type..
+  ///
+  ///     JS_BUILTIN('returns:bool;effects:none;depends:none',
+  ///                JsBuiltin.isNullType, type);
+  isNullTypeRti,
+
+  /// Returns whether the given type is _the_ Dart Object type.
+  ///
+  ///     JS_BUILTIN('returns:bool;effects:none;depends:none',
+  ///                JsBuiltin.isDartObjectType, type);
+  isDartObjectTypeRti,
+
   /// Returns the metadata of the given [index].
   ///
   ///     JS_BUILTIN('returns:var;effects:none;depends:none',
diff --git a/sdk/lib/_internal/pub/README.md b/sdk/lib/_internal/pub/README.md
index 6191ea3..cb92901 100644
--- a/sdk/lib/_internal/pub/README.md
+++ b/sdk/lib/_internal/pub/README.md
@@ -1,4 +1,4 @@
-# Contibuting to pub
+# Contributing to pub
 
 Thanks for being interested in contributing to pub! Contributing to a new
 project can be hard: there's a lot of new code and practices to learn. This
diff --git a/sdk/lib/_internal/pub/lib/src/barback/dependency_computer.dart b/sdk/lib/_internal/pub/lib/src/barback/dependency_computer.dart
index 9e46b46..facf140 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/dependency_computer.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/dependency_computer.dart
@@ -254,6 +254,9 @@
           String packageName)
       : _dependencyComputer = dependencyComputer,
         _package = dependencyComputer._graph.packages[packageName] {
+    var isRootPackage =
+        packageName == _dependencyComputer._graph.entrypoint.root.name;
+
     // If [_package] uses its own transformers, there will be fewer transformers
     // running on [_package] while its own transformers are loading than there
     // will be once all its transformers are finished loading. To handle this,
@@ -262,6 +265,9 @@
     // smaller.
     for (var phase in _package.pubspec.transformers) {
       for (var config in phase) {
+        // Ignore non-root transformers on non-public files.
+        if (!isRootPackage && !config.canTransformPublicFiles) continue;
+
         var id = config.id;
         try {
           if (id.package != _package.name) {
diff --git a/sdk/lib/_internal/pub/lib/src/barback/transformer_isolate.dart b/sdk/lib/_internal/pub/lib/src/barback/transformer_isolate.dart
index 65ba68f..e969279 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/transformer_isolate.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/transformer_isolate.dart
@@ -94,7 +94,7 @@
         // error message.
         var missingTransformer = idsToUrls.keys.firstWhere((id) =>
             firstErrorLine.startsWith(
-                "Uncaught Error: Load Error: Failure getting ") &&
+                "Load Error for") &&
             firstErrorLine.contains(idsToUrls[id].path),
             orElse: () => throw error);
         var packageUri = idToPackageUri(idsToAssetIds[missingTransformer]);
diff --git a/sdk/lib/_internal/pub/lib/src/command_runner.dart b/sdk/lib/_internal/pub/lib/src/command_runner.dart
index 96382da..ce0645d 100644
--- a/sdk/lib/_internal/pub/lib/src/command_runner.dart
+++ b/sdk/lib/_internal/pub/lib/src/command_runner.dart
@@ -130,10 +130,12 @@
       if (options['trace']) {
         log.dumpTranscript();
       } else if (!isUserFacingException(error)) {
+        // TODO(23505): Implement proper shell escaping, not a partial hack.
+        protectArgument(String x) => x.contains(' ') ? '"$x"' : x;
         log.error("""
 This is an unexpected error. Please run
 
-    pub --trace ${options.arguments.map((arg) => "'$arg'").join(' ')}
+    pub --trace ${options.arguments.map(protectArgument).join(' ')}
 
 and include the results in a bug report on http://dartbug.com/new.
 """);
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart
index 73b1e06..0d664bb 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart
@@ -31,7 +31,7 @@
       var pub = startPubServe();
       pub.stderr.expect("Unhandled exception:");
       pub.stderr.expect(
-          startsWith("Uncaught Error: Load Error: Failure getting "));
+          startsWith("Load Error for "));
       pub.shouldExit(1);
     });
   });
diff --git a/sdk/lib/_internal/pub/test/transformer/ignores_a_transformer_on_test_files_in_a_dependency_test.dart b/sdk/lib/_internal/pub/test/transformer/ignores_a_transformer_on_test_files_in_a_dependency_test.dart
new file mode 100644
index 0000000..c62c00a
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/ignores_a_transformer_on_test_files_in_a_dependency_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+import '../serve/utils.dart';
+
+main() {
+  initConfig();
+  // Regression test for issue 23480
+  integration("ignores a transformer on test files in a dependency", () {
+    servePackages((builder) {
+      builder.serveRepoPackage('barback');
+
+      builder.serve("bar", "1.2.3", contents: [
+        d.dir("lib", [
+          // Make this invalid so that if it does get loaded, pub will
+          // definitely throw an error.
+          d.file("bar.dart", "{invalid Dart code)")
+        ])
+      ]);
+
+      builder.serve("foo", "1.2.3",
+        pubspec: {
+        "name": "foo",
+        "version": "1.0.0",
+        "dev_dependencies": {
+          "bar": "any"
+        },
+        "transformers": [{
+          "bar": {"\$include": "test/**"}
+        }]
+      }, contents: [
+        d.dir("test", [
+          d.file("my_test.dart", "void main() {}")
+        ])
+      ]);
+    });
+
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "dependencies": {"foo": "any"}
+      }),
+      d.dir("web", [
+        d.file("foo.txt", "foo")
+      ])
+    ]).create();
+
+    pubGet();
+
+    pubServe();
+    requestShouldSucceed("foo.txt", "foo");
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 044638d..77420d0 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -48,7 +48,7 @@
  * use [asBroadcastStream] to create a broadcast stream on top of the
  * non-broadcast stream.
  *
- * On either kind of stream, stream transformationss, such as [where] and
+ * On either kind of stream, stream transformations, such as [where] and
  * [skip], return the same type of stream as the one the method was called on,
  * unless otherwise noted.
  *
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index fa0886d..d3624ab 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -693,9 +693,10 @@
       return true;
     } else if (object is Map) {
       _checkCycle(object);
-      writeMap(object);
+      // writeMap can fail if keys are not all strings.
+      var success = writeMap(object);
       _removeSeen(object);
-      return true;
+      return success;
     } else {
       return false;
     }
@@ -715,17 +716,33 @@
   }
 
   /** Serializes a [Map]. */
-  void writeMap(Map<String, Object> map) {
+  bool writeMap(Map<String, Object> map) {
+    if (map.isEmpty) {
+      writeString("{}");
+      return true;
+    }
+    List keyValueList = new List(map.length * 2);
+    int i = 0;
+    bool allStringKeys = true;
+    map.forEach((key, value) {
+      if (key is! String) {
+        allStringKeys = false;
+      }
+      keyValueList[i++] = key;
+      keyValueList[i++] = value;
+    });
+    if (!allStringKeys) return false;
     writeString('{');
     String separator = '"';
-    map.forEach((String key, value) {
+    for (int i = 0; i < keyValueList.length; i += 2) {
       writeString(separator);
       separator = ',"';
-      writeStringContent(key);
+      writeStringContent(keyValueList[i]);
       writeString('":');
-      writeObject(value);
-    });
+      writeObject(keyValueList[i + 1]);
+    }
     writeString('}');
+    return true;
   }
 }
 
@@ -763,29 +780,39 @@
     }
   }
 
-  void writeMap(Map map) {
+  bool writeMap(Map map) {
     if (map.isEmpty) {
-      writeString('{}');
-    } else {
-      writeString('{\n');
-      _indentLevel++;
-      bool first = true;
-      map.forEach((String key, Object value) {
-        if (!first) {
-          writeString(",\n");
-        }
-        writeIndentation(_indentLevel);
-        writeString('"');
-        writeStringContent(key);
-        writeString('": ');
-        writeObject(value);
-        first = false;
-      });
-      writeString('\n');
-      _indentLevel--;
-      writeIndentation(_indentLevel);
-      writeString('}');
+      writeString("{}");
+      return true;
     }
+    List keyValueList = new List(map.length * 2);
+    int i = 0;
+    bool allStringKeys = true;
+    map.forEach((key, value) {
+      if (key is! String) {
+        allStringKeys = false;
+      }
+      keyValueList[i++] = key;
+      keyValueList[i++] = value;
+    });
+    if (!allStringKeys) return false;
+    writeString('{\n');
+    _indentLevel++;
+    String separator = "";
+    for (int i = 0; i < keyValueList.length; i += 2) {
+      writeString(separator);
+      separator = ",\n";
+      writeIndentation(_indentLevel);
+      writeString('"');
+      writeStringContent(keyValueList[i]);
+      writeString('": ');
+      writeObject(keyValueList[i + 1]);
+    }
+    writeString('\n');
+    _indentLevel--;
+    writeIndentation(_indentLevel);
+    writeString('}');
+    return true;
   }
 }
 
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index e435b1e..c22283a 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -102,6 +102,17 @@
   }
 
   /**
+   * Creates an empty iterable.
+   *
+   * The empty iterable has no elements, and iterating it always stops
+   * immediately.
+   *
+   * An empty iterable can be used in places where you always that
+   * the iterable you would otherwise create is empty.
+   */
+  const factory Iterable.empty() = EmptyIterable<E>;
+
+  /**
    * Returns a new `Iterator` that allows iterating the elements of this
    * `Iterable`.
    *
diff --git a/sdk/lib/developer/developer.dart b/sdk/lib/developer/developer.dart
index db56aec..4df565e 100644
--- a/sdk/lib/developer/developer.dart
+++ b/sdk/lib/developer/developer.dart
@@ -11,6 +11,10 @@
 ///
 library dart.developer;
 
+import 'dart:convert';
+
+part 'profiler.dart';
+
 /// If [when] is true, stop the program as if a breakpoint where hit at the
 /// following statement. Returns the value of [when]. Some debuggers may
 /// display [msg].
diff --git a/sdk/lib/developer/developer_sources.gypi b/sdk/lib/developer/developer_sources.gypi
index fa6a87c..adbaea9 100644
--- a/sdk/lib/developer/developer_sources.gypi
+++ b/sdk/lib/developer/developer_sources.gypi
@@ -5,6 +5,7 @@
 {
   'sources': [
     'developer.dart',
+    'profiler.dart',
     # The above file needs to be first if additional parts are added to the lib.
   ],
 }
diff --git a/sdk/lib/developer/profiler.dart b/sdk/lib/developer/profiler.dart
new file mode 100644
index 0000000..566d015
--- /dev/null
+++ b/sdk/lib/developer/profiler.dart
@@ -0,0 +1,197 @@
+// 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.
+
+part of dart.developer;
+
+/// A UserTag can be used to group samples in the Observatory profiler.
+abstract class UserTag {
+  /// The maximum number of UserTag instances that can be created by a program.
+  static const MAX_USER_TAGS = 64;
+
+  factory UserTag(String label) => new _FakeUserTag(label);
+
+  /// Label of [this].
+  String get label;
+
+  /// Make [this] the current tag for the isolate. Returns the current tag
+  /// before setting.
+  UserTag makeCurrent();
+
+  /// The default [UserTag] with label 'Default'.
+  static UserTag get defaultTag => _FakeUserTag._defaultTag;
+}
+
+// This is a fake implementation of UserTag so that code can compile and run
+// in dart2js.
+class _FakeUserTag implements UserTag {
+  static Map _instances = {};
+
+  _FakeUserTag.real(this.label);
+
+  factory _FakeUserTag(String label) {
+    // Canonicalize by name.
+    var existingTag = _instances[label];
+    if (existingTag != null) {
+      return existingTag;
+    }
+    // Throw an exception if we've reached the maximum number of user tags.
+    if (_instances.length == UserTag.MAX_USER_TAGS) {
+      throw new UnsupportedError(
+          'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.');
+    }
+    // Create a new instance and add it to the instance map.
+    var instance = new _FakeUserTag.real(label);
+    _instances[label] = instance;
+    return instance;
+  }
+
+  final String label;
+
+  UserTag makeCurrent() {
+    var old = _currentTag;
+    _currentTag = this;
+    return old;
+  }
+
+  static final UserTag _defaultTag = new _FakeUserTag('Default');
+}
+
+var _currentTag = _FakeUserTag._defaultTag;
+
+/// Returns the current [UserTag] for the isolate.
+UserTag getCurrentTag() {
+  return _currentTag;
+}
+
+/// Abstract [Metric] class. Metric names must be unique, are hierarchical,
+/// and use periods as separators. For example, 'a.b.c'. Uniqueness is only
+/// enforced when a Metric is registered. The name of a metric cannot contain
+/// the slash ('/') character.
+abstract class Metric {
+  /// [name] of this metric.
+  final String name;
+  /// [description] of this metric.
+  final String description;
+
+  Metric(this.name, this.description) {
+    if ((name == 'vm') || name.contains('/')) {
+      throw new ArgumentError('Invalid Metric name.');
+    }
+
+  }
+
+  Map _toJSON();
+}
+
+/// A measured value with a min and max. Initial value is min. Value will
+/// be clamped to the interval [min, max].
+class Gauge extends Metric {
+  final double min;
+  final double max;
+
+  double _value;
+  double get value => _value;
+  set value(double v) {
+    if (v < min) {
+      v = min;
+    } else if (v > max) {
+      v = max;
+    }
+    _value = v;
+  }
+
+  Gauge(String name, String description, this.min, this.max)
+      : super(name, description) {
+    if (min is! double) {
+      throw new ArgumentError('min must be a double');
+    }
+    if (max is! double) {
+      throw new ArgumentError('max must be a double');
+    }
+    if (!(min < max)) {
+      throw new ArgumentError('min must be less than max');
+    }
+    _value = min;
+  }
+
+  Map _toJSON() {
+    var map = {
+      'type': 'Gauge',
+      'id': 'metrics/$name',
+      'name': name,
+      'description': description,
+      'value': value,
+      'min': min,
+      'max': max,
+    };
+    return map;
+  }
+}
+
+
+/// A changing value. Initial value is 0.0.
+class Counter extends Metric {
+  Counter(String name, String description)
+      : super(name, description);
+
+  double _value = 0.0;
+  double get value => _value;
+  set value(double v) {
+    _value = v;
+  }
+
+  Map _toJSON() {
+    var map = {
+      'type': 'Counter',
+      'id': 'metrics/$name',
+      'name': name,
+      'description': description,
+      'value': value,
+    };
+    return map;
+  }
+}
+
+class Metrics {
+  static final Map<String, Metric> _metrics = new Map<String, Metric>();
+
+  /// Register [Metric]s to make them visible to Observatory.
+  static void register(Metric metric) {
+    if (metric is! Metric) {
+      throw new ArgumentError('metric must be a Metric');
+    }
+    if (_metrics[metric.name] != null) {
+      throw new ArgumentError('Registered metrics have unique names');
+    }
+    _metrics[metric.name] = metric;
+  }
+
+  /// Deregister [Metric]s to make them not visible to Observatory.
+  static void deregister(Metric metric) {
+    if (metric is! Metric) {
+      throw new ArgumentError('metric must be a Metric');
+    }
+    _metrics.remove(metric.name);
+  }
+
+  static String _printMetric(String id) {
+    var metric = _metrics[id];
+    if (metric == null) {
+      return null;
+    }
+    return JSON.encode(metric._toJSON());
+  }
+
+  static String _printMetrics() {
+    var metrics = [];
+    for (var metric in _metrics.values) {
+      metrics.add(metric._toJSON());
+    }
+    var map = {
+      'type': 'MetricList',
+      'metrics': metrics,
+    };
+    return JSON.encode(map);
+  }
+}
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index c96ee3c..34cbd41 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -13264,7 +13264,7 @@
    *
    * Those attributes are: attributes, lastChild, children, previousNode and tagName.
    */
-  bool get _hasCorruptedAttributes {
+  static bool _hasCorruptedAttributes(Element element) {
      return JS('bool', r'''
        (function(element) {
          if (!(element.attributes instanceof NamedNodeMap)) {
@@ -13282,7 +13282,7 @@
 	   }
 	 }
 	 return false;
-          })(#)''', this);
+          })(#)''', element);
   }
 
   @DomName('Element.offsetHeight')
@@ -40785,60 +40785,99 @@
 
   /// Aggressively try to remove node.
   void _removeNode(Node node, Node parent) {
-    // If we have the parent, it's presumably already passed more sanitization or
-    // is the fragment, so ask it to remove the child. And if that fails try to
-    // set the outer html.
+    // If we have the parent, it's presumably already passed more sanitization
+    // or is the fragment, so ask it to remove the child. And if that fails
+    // try to set the outer html.
     if (parent == null) {
       node.remove();
     } else {
       parent._removeChild(node);
     }
   }
-  
+
+  /// Sanitize the element, assuming we can't trust anything about it.
+  void _sanitizeUntrustedElement(Element element, Node parent) {
+    // If the _hasCorruptedAttributes does not successfully return false,
+    // then we consider it corrupted and remove.
+    // TODO(alanknight): This is a workaround because on Firefox
+    // embed/object
+    // tags typeof is "function", not "object". We don't recognize them, and
+    // can't call methods. This does mean that you can't explicitly allow an
+    // embed tag. The only thing that will let it through is a null
+    // sanitizer that doesn't traverse the tree at all. But sanitizing while
+    // allowing embeds seems quite unlikely.
+    var corrupted = true;
+    var attrs;
+    var isAttr;
+    try {
+      // If getting/indexing attributes throws, count that as corrupt.
+      attrs = element.attributes;
+      isAttr = attrs['is'];
+      corrupted = Element._hasCorruptedAttributes(element);
+    } catch(e) {}
+     var elementText = 'element unprintable';
+    try {
+      elementText = element.toString();
+    } catch(e) {}
+    var elementTagName = 'element tag unavailable';
+    try {
+      elementTagName = element.tagName;
+    } catch(e) {}
+    _sanitizeElement(element, parent, corrupted, elementText, elementTagName,
+        attrs, isAttr);
+  }
+
+  /// Having done basic sanity checking on the element, and computed the
+  /// important attributes we want to check, remove it if it's not valid
+  /// or not allowed, either as a whole or particular attributes.
+  void _sanitizeElement(Element element, Node parent, bool corrupted,
+      String text, String tag, Map attrs, String isAttr) {
+    if (false != corrupted) {
+      window.console.warn(
+          'Removing element due to corrupted attributes on <$text>');
+       _removeNode(element, parent);
+       return;
+    }
+    if (!validator.allowsElement(element)) {
+      window.console.warn(
+          'Removing disallowed element <$tag>');
+      _removeNode(element, parent);
+      return;
+    }
+
+    if (isAttr != null) {
+      if (!validator.allowsAttribute(element, 'is', isAttr)) {
+        window.console.warn('Removing disallowed type extension '
+            '<$tag is="$isAttr">');
+        _removeNode(element, parent);
+        return;
+      }
+    }
+
+    // TODO(blois): Need to be able to get all attributes, irrespective of
+    // XMLNS.
+    var keys = attrs.keys.toList();
+    for (var i = attrs.length - 1; i >= 0; --i) {
+      var name = keys[i];
+      if (!validator.allowsAttribute(element, name.toLowerCase(),
+          attrs[name])) {
+        window.console.warn('Removing disallowed attribute '
+            '<$tag $name="${attrs[name]}">');
+        attrs.remove(name);
+      }
+    }
+
+    if (element is TemplateElement) {
+      TemplateElement template = element;
+      sanitizeTree(template.content);
+     }
+  }
+
+  /// Sanitize the node and its children recursively.
   void sanitizeNode(Node node, Node parent) {
     switch (node.nodeType) {
       case Node.ELEMENT_NODE:
-        Element element = node;
-        if (element._hasCorruptedAttributes) {
-          window.console.warn('Removing element due to corrupted attributes on <${element}>');
-          _removeNode(node, parent);
-          break;
-        }
-        var attrs = element.attributes;
-        if (!validator.allowsElement(element)) {
-          window.console.warn(
-              'Removing disallowed element <${element.tagName}>');
-          _removeNode(node, parent);
-          break;
-        }
-
-        var isAttr = attrs['is'];
-        if (isAttr != null) {
-          if (!validator.allowsAttribute(element, 'is', isAttr)) {
-            window.console.warn('Removing disallowed type extension '
-                '<${element.tagName} is="$isAttr">');
-            _removeNode(node, parent);
-            break;
-          }
-        }
-
-        // TODO(blois): Need to be able to get all attributes, irrespective of
-        // XMLNS.
-        var keys = attrs.keys.toList();
-        for (var i = attrs.length - 1; i >= 0; --i) {
-          var name = keys[i];
-          if (!validator.allowsAttribute(element, name.toLowerCase(),
-              attrs[name])) {
-            window.console.warn('Removing disallowed attribute '
-                '<${element.tagName} $name="${attrs[name]}">');
-            attrs.remove(name);
-          }
-        }
-
-        if (element is TemplateElement) {
-          TemplateElement template = element;
-          sanitizeTree(template.content);
-        }
+        _sanitizeUntrustedElement(node, parent);
         break;
       case Node.COMMENT_NODE:
       case Node.DOCUMENT_FRAGMENT_NODE:
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 25d91f6..5ab6241 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -12713,7 +12713,7 @@
    * Those attributes are: attributes, lastChild, children, previousNode and tagName.
    */
   // Dartium isn't affected by these attacks, because it goes directly to the C++ API.
-  bool get _hasCorruptedAttributes => false;
+  static bool _hasCorruptedAttributes(Element element) => false;
 
   @DomName('Element.offsetHeight')
   @DocsEditable()
@@ -40715,60 +40715,99 @@
 
   /// Aggressively try to remove node.
   void _removeNode(Node node, Node parent) {
-    // If we have the parent, it's presumably already passed more sanitization or
-    // is the fragment, so ask it to remove the child. And if that fails try to
-    // set the outer html.
+    // If we have the parent, it's presumably already passed more sanitization
+    // or is the fragment, so ask it to remove the child. And if that fails
+    // try to set the outer html.
     if (parent == null) {
       node.remove();
     } else {
       parent._removeChild(node);
     }
   }
-  
+
+  /// Sanitize the element, assuming we can't trust anything about it.
+  void _sanitizeUntrustedElement(Element element, Node parent) {
+    // If the _hasCorruptedAttributes does not successfully return false,
+    // then we consider it corrupted and remove.
+    // TODO(alanknight): This is a workaround because on Firefox
+    // embed/object
+    // tags typeof is "function", not "object". We don't recognize them, and
+    // can't call methods. This does mean that you can't explicitly allow an
+    // embed tag. The only thing that will let it through is a null
+    // sanitizer that doesn't traverse the tree at all. But sanitizing while
+    // allowing embeds seems quite unlikely.
+    var corrupted = true;
+    var attrs;
+    var isAttr;
+    try {
+      // If getting/indexing attributes throws, count that as corrupt.
+      attrs = element.attributes;
+      isAttr = attrs['is'];
+      corrupted = Element._hasCorruptedAttributes(element);
+    } catch(e) {}
+     var elementText = 'element unprintable';
+    try {
+      elementText = element.toString();
+    } catch(e) {}
+    var elementTagName = 'element tag unavailable';
+    try {
+      elementTagName = element.tagName;
+    } catch(e) {}
+    _sanitizeElement(element, parent, corrupted, elementText, elementTagName,
+        attrs, isAttr);
+  }
+
+  /// Having done basic sanity checking on the element, and computed the
+  /// important attributes we want to check, remove it if it's not valid
+  /// or not allowed, either as a whole or particular attributes.
+  void _sanitizeElement(Element element, Node parent, bool corrupted,
+      String text, String tag, Map attrs, String isAttr) {
+    if (false != corrupted) {
+      window.console.warn(
+          'Removing element due to corrupted attributes on <$text>');
+       _removeNode(element, parent);
+       return;
+    }
+    if (!validator.allowsElement(element)) {
+      window.console.warn(
+          'Removing disallowed element <$tag>');
+      _removeNode(element, parent);
+      return;
+    }
+
+    if (isAttr != null) {
+      if (!validator.allowsAttribute(element, 'is', isAttr)) {
+        window.console.warn('Removing disallowed type extension '
+            '<$tag is="$isAttr">');
+        _removeNode(element, parent);
+        return;
+      }
+    }
+
+    // TODO(blois): Need to be able to get all attributes, irrespective of
+    // XMLNS.
+    var keys = attrs.keys.toList();
+    for (var i = attrs.length - 1; i >= 0; --i) {
+      var name = keys[i];
+      if (!validator.allowsAttribute(element, name.toLowerCase(),
+          attrs[name])) {
+        window.console.warn('Removing disallowed attribute '
+            '<$tag $name="${attrs[name]}">');
+        attrs.remove(name);
+      }
+    }
+
+    if (element is TemplateElement) {
+      TemplateElement template = element;
+      sanitizeTree(template.content);
+     }
+  }
+
+  /// Sanitize the node and its children recursively.
   void sanitizeNode(Node node, Node parent) {
     switch (node.nodeType) {
       case Node.ELEMENT_NODE:
-        Element element = node;
-        if (element._hasCorruptedAttributes) {
-          window.console.warn('Removing element due to corrupted attributes on <${element}>');
-          _removeNode(node, parent);
-          break;
-        }
-        var attrs = element.attributes;
-        if (!validator.allowsElement(element)) {
-          window.console.warn(
-              'Removing disallowed element <${element.tagName}>');
-          _removeNode(node, parent);
-          break;
-        }
-
-        var isAttr = attrs['is'];
-        if (isAttr != null) {
-          if (!validator.allowsAttribute(element, 'is', isAttr)) {
-            window.console.warn('Removing disallowed type extension '
-                '<${element.tagName} is="$isAttr">');
-            _removeNode(node, parent);
-            break;
-          }
-        }
-
-        // TODO(blois): Need to be able to get all attributes, irrespective of
-        // XMLNS.
-        var keys = attrs.keys.toList();
-        for (var i = attrs.length - 1; i >= 0; --i) {
-          var name = keys[i];
-          if (!validator.allowsAttribute(element, name.toLowerCase(),
-              attrs[name])) {
-            window.console.warn('Removing disallowed attribute '
-                '<${element.tagName} $name="${attrs[name]}">');
-            attrs.remove(name);
-          }
-        }
-
-        if (element is TemplateElement) {
-          TemplateElement template = element;
-          sanitizeTree(template.content);
-        }
+        _sanitizeUntrustedElement(node, parent);
         break;
       case Node.COMMENT_NODE:
       case Node.DOCUMENT_FRAGMENT_NODE:
diff --git a/sdk/lib/internal/iterable.dart b/sdk/lib/internal/iterable.dart
index 0a59b0e..ff03d1a 100644
--- a/sdk/lib/internal/iterable.dart
+++ b/sdk/lib/internal/iterable.dart
@@ -658,7 +658,7 @@
  * The always empty [Iterable].
  */
 class EmptyIterable<E> extends Iterable<E>
-                      implements EfficientLengthIterable<E> {
+                       implements EfficientLengthIterable<E> {
   const EmptyIterable();
 
   Iterator<E> get iterator => const EmptyIterator();
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index df35660..8799158 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -573,7 +573,7 @@
    *
    * Returns a [:Future<int>:] that completes with the number of bytes read.
    */
-  Future<int> readInto(List<int> buffer, [int start, int end]);
+  Future<int> readInto(List<int> buffer, [int start = 0, int end]);
 
   /**
    * Synchronously reads into an existing List<int> from the file. If [start] is
@@ -584,7 +584,7 @@
    *
    * Throws a [FileSystemException] if the operation fails.
    */
-  int readIntoSync(List<int> buffer, [int start, int end]);
+  int readIntoSync(List<int> buffer, [int start = 0, int end]);
 
   /**
    * Writes a single byte to the file. Returns a
@@ -609,7 +609,8 @@
    * Returns a [:Future<RandomAccessFile>:] that completes with this
    * [RandomAccessFile] when the write completes.
    */
-  Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]);
+  Future<RandomAccessFile> writeFrom(
+      List<int> buffer, [int start = 0, int end]);
 
   /**
    * Synchronously writes from a [List<int>] to the file. It will read the
@@ -619,7 +620,7 @@
    *
    * Throws a [FileSystemException] if the operation fails.
    */
-  void writeFromSync(List<int> buffer, [int start, int end]);
+  void writeFromSync(List<int> buffer, [int start = 0, int end]);
 
   /**
    * Writes a string to the file using the given [Encoding]. Returns a
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 2dac1b8..a98d948 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -347,23 +347,25 @@
         mode != FileMode.APPEND) {
       return new Future.error(new ArgumentError());
     }
-    return _IOService._dispatch(_FILE_OPEN, [path, mode._mode]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "Cannot open file", path);
-      }
-      return new _RandomAccessFile(response, path);
-    });
+    return _IOService._dispatch(_FILE_OPEN, [path, mode._mode])
+        .then((response) {
+          if (_isErrorResponse(response)) {
+            throw _exceptionFromResponse(response, "Cannot open file", path);
+          }
+          return new _RandomAccessFile(response, path);
+        });
   }
 
   Future<int> length() {
-    return _IOService._dispatch(_FILE_LENGTH_FROM_PATH, [path]).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response,
-                                     "Cannot retrieve length of file",
-                                     path);
-      }
-      return response;
-    });
+    return _IOService._dispatch(_FILE_LENGTH_FROM_PATH, [path])
+        .then((response) {
+          if (_isErrorResponse(response)) {
+            throw _exceptionFromResponse(response,
+                                         "Cannot retrieve length of file",
+                                         path);
+          }
+          return response;
+        });
   }
 
 
@@ -688,14 +690,14 @@
     return result;
   }
 
-  Future<int> readInto(List<int> buffer, [int start, int end]) {
+  Future<int> readInto(List<int> buffer, [int start = 0, int end]) {
     if (buffer is !List ||
         (start != null && start is !int) ||
         (end != null && end is !int)) {
       throw new ArgumentError();
     }
-    if (start == null) start = 0;
-    if (end == null) end = buffer.length;
+    end = RangeError.checkValidRange(start, end, buffer.length);
+    if (end == start) return new Future.value(0);
     int length = end - start;
     return _dispatch(_FILE_READ_INTO, [_id, length]).then((response) {
       if (_isErrorResponse(response)) {
@@ -710,23 +712,17 @@
     });
   }
 
-  static void _checkReadWriteListArguments(int length, int start, int end) {
-    RangeError.checkValidRange(start, end, length);
-  }
-
   external static _readInto(int id, List<int> buffer, int start, int end);
 
-  int readIntoSync(List<int> buffer, [int start, int end]) {
+  int readIntoSync(List<int> buffer, [int start = 0, int end]) {
     _checkAvailable();
     if (buffer is !List ||
         (start != null && start is !int) ||
         (end != null && end is !int)) {
       throw new ArgumentError();
     }
-    if (start == null) start = 0;
-    if (end == null) end = buffer.length;
+    end = RangeError.checkValidRange(start, end, buffer.length);
     if (end == start) return 0;
-    _checkReadWriteListArguments(buffer.length, start, end);
     var result = _readInto(_id, buffer, start, end);
     if (result is OSError) {
       throw new FileSystemException("readInto failed", path, result);
@@ -766,13 +762,15 @@
     return result;
   }
 
-  Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) {
-    if ((buffer is !List && buffer is !ByteData) ||
+  Future<RandomAccessFile> writeFrom(
+      List<int> buffer, [int start = 0, int end]) {
+    if ((buffer is !List) ||
         (start != null && start is !int) ||
         (end != null && end is !int)) {
       throw new ArgumentError("Invalid arguments to writeFrom");
     }
-
+    end = RangeError.checkValidRange(start, end, buffer.length);
+    if (end == start) return new Future.value(this);
     _BufferAndStart result;
     try {
       result = _ensureFastAndSerializableByteData(buffer, start, end);
@@ -797,17 +795,15 @@
 
   external static _writeFrom(int id, List<int> buffer, int start, int end);
 
-  void writeFromSync(List<int> buffer, [int start, int end]) {
+  void writeFromSync(List<int> buffer, [int start = 0, int end]) {
     _checkAvailable();
     if (buffer is !List ||
         (start != null && start is !int) ||
         (end != null && end is !int)) {
       throw new ArgumentError("Invalid arguments to writeFromSync");
     }
-    if (start == null) start = 0;
-    if (end == null) end = buffer.length;
+    end = RangeError.checkValidRange(start, end, buffer.length);
     if (end == start) return;
-    _checkReadWriteListArguments(buffer.length, start, end);
     _BufferAndStart bufferAndStart =
         _ensureFastAndSerializableByteData(buffer, start, end);
     var result = _writeFrom(_id,
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index 134cd21..6b86095 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -39,7 +39,7 @@
  *       Map<String, String> envVars = Platform.environment;
  *       print(envVars['PATH']);
  *     }
- * 
+ *
  * ## Determine the OS
  *
  * You can get the name of the operating system as a string with the
@@ -53,7 +53,7 @@
  *       String os = Platform.operatingSystem;
  *       // Or, use a predicate getter.
  *       if (Platform.isMacOS) {
- *         Print('is a Mac'); 
+ *         Print('is a Mac');
  *       } else {
  *        print('is not a Mac');
  *       }
@@ -62,7 +62,7 @@
  * ## Other resources
  *
  * [Dart by Example](https://www.dartlang.org/dart-by-example/#dart-io-and-command-line-apps)
- * provides additional task-oriented code samples that show how to use 
+ * provides additional task-oriented code samples that show how to use
  * various API from the [dart:io] library.
  */
 class Platform {
@@ -131,6 +131,8 @@
    * Returns the path of the executable used to run the script in this
    * isolate.
    *
+   * If supported by the platform the returned path will be absolute.
+   *
    * If the execution environment does not support [executable] an empty
    * string is returned.
    */
diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart
index 6de5032..849de82 100644
--- a/sdk/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/js/dart2js/js_dart2js.dart
@@ -141,6 +141,39 @@
     if (arguments == null) {
       return _wrapToDart(JS('', 'new #()', constr));
     }
+
+    if (JS('bool', '# instanceof Array', arguments)) {
+      int argumentCount = JS('int', '#.length', arguments);
+      switch (argumentCount) {
+        case 0:
+          return _wrapToDart(JS('', 'new #()', constr));
+
+        case 1:
+          var arg0 = _convertToJS(JS('', '#[0]', arguments));
+          return _wrapToDart(JS('', 'new #(#)', constr, arg0));
+
+        case 2:
+          var arg0 = _convertToJS(JS('', '#[0]', arguments));
+          var arg1 = _convertToJS(JS('', '#[1]', arguments));
+          return _wrapToDart(JS('', 'new #(#, #)', constr, arg0, arg1));
+
+        case 3:
+          var arg0 = _convertToJS(JS('', '#[0]', arguments));
+          var arg1 = _convertToJS(JS('', '#[1]', arguments));
+          var arg2 = _convertToJS(JS('', '#[2]', arguments));
+          return _wrapToDart(
+              JS('', 'new #(#, #, #)', constr, arg0, arg1, arg2));
+
+        case 4:
+          var arg0 = _convertToJS(JS('', '#[0]', arguments));
+          var arg1 = _convertToJS(JS('', '#[1]', arguments));
+          var arg2 = _convertToJS(JS('', '#[2]', arguments));
+          var arg3 = _convertToJS(JS('', '#[3]', arguments));
+          return _wrapToDart(
+              JS('', 'new #(#, #, #, #)', constr, arg0, arg1, arg2, arg3));
+      }
+    }
+
     // The following code solves the problem of invoking a JavaScript
     // constructor with an unknown number arguments.
     // First bind the constructor to the argument list using bind.apply().
@@ -154,9 +187,16 @@
     JS('String', 'String(#)', factoryFunction);
     // This could return an UnknownJavaScriptObject, or a native
     // object for which there is an interceptor
-    var jsObj = JS('JavaScriptObject', 'new #()', factoryFunction);
+    var jsObj = JS('', 'new #()', factoryFunction);
 
     return _wrapToDart(jsObj);
+
+    // TODO(sra): Investigate:
+    //
+    //     var jsObj = JS('', 'Object.create(#.prototype)', constr);
+    //     JS('', '#.apply(#, #)', constr, jsObj,
+    //         []..addAll(arguments.map(_convertToJS)));
+    //     return _wrapToDart(jsObj);
   }
 
   /**
@@ -510,25 +550,28 @@
   // `undefined` in Javascprit). See dartbug.com/20305 for details.
   if (o == null || o is String || o is num || o is bool) {
     return o;
-  } else if (o is Blob || o is Event || o is KeyRange || o is ImageData
-      || o is Node || o is TypedData || o is Window) {
-    return o;
-  } else if (o is DateTime) {
-    return Primitives.lazyAsJsDate(o);
-  } else if (o is JsObject) {
+  }
+  if (o is JsObject) {
     return o._jsObject;
-  } else if (o is Function) {
+  }
+  if (o is Blob || o is Event || o is KeyRange || o is ImageData || o is Node ||
+      o is TypedData || o is Window) {
+    return o;
+  }
+  if (o is DateTime) {
+    return Primitives.lazyAsJsDate(o);
+  }
+  if (o is Function) {
     return _getJsProxy(o, _JS_FUNCTION_PROPERTY_NAME, (o) {
       var jsFunction = _convertDartFunction(o);
       // set a property on the JS closure referencing the Dart closure
       _defineProperty(jsFunction, _DART_CLOSURE_PROPERTY_NAME, o);
       return jsFunction;
     });
-  } else {
-    var ctor = _dartProxyCtor;
-    return _getJsProxy(o, _JS_OBJECT_PROPERTY_NAME,
-        (o) => JS('', 'new #(#)', ctor, o));
   }
+  var ctor = _dartProxyCtor;
+  return _getJsProxy(o, _JS_OBJECT_PROPERTY_NAME,
+      (o) => JS('', 'new #(#)', ctor, o));
 }
 
 Object _getJsProxy(o, String propertyName, createProxy(o)) {
@@ -567,13 +610,13 @@
   if (JS('bool', 'typeof # == "function"', o)) {
     return _getDartProxy(o, _DART_CLOSURE_PROPERTY_NAME,
         (o) => new JsFunction._fromJs(o));
-  } else if (JS('bool', '# instanceof Array', o)) {
+  }
+  if (JS('bool', '# instanceof Array', o)) {
     return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
         (o) => new JsArray._fromJs(o));
-  } else {
-    return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
-        (o) => new JsObject._fromJs(o));
   }
+  return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
+      (o) => new JsObject._fromJs(o));
 }
 
 Object _getDartProxy(o, String propertyName, createProxy(o)) {
diff --git a/sdk/lib/profiler/profiler.dart b/sdk/lib/profiler/profiler.dart
index 470638b..84add7b 100644
--- a/sdk/lib/profiler/profiler.dart
+++ b/sdk/lib/profiler/profiler.dart
@@ -2,199 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/// Instrument your code with counters, gauges, and more.
+/// Please see 'dart:developer'.
+@Deprecated("Dart SDK 1.12")
 library dart.profiler;
 
-import 'dart:convert';
-
-/// A UserTag can be used to group samples in the Observatory profiler.
-abstract class UserTag {
-  /// The maximum number of UserTag instances that can be created by a program.
-  static const MAX_USER_TAGS = 64;
-
-  factory UserTag(String label) => new _FakeUserTag(label);
-
-  /// Label of [this].
-  String get label;
-
-  /// Make [this] the current tag for the isolate. Returns the current tag
-  /// before setting.
-  UserTag makeCurrent();
-
-  /// The default [UserTag] with label 'Default'.
-  static UserTag get defaultTag => _FakeUserTag._defaultTag;
-}
-
-// This is a fake implementation of UserTag so that code can compile and run
-// in dart2js.
-class _FakeUserTag implements UserTag {
-  static Map _instances = {};
-
-  _FakeUserTag.real(this.label);
-
-  factory _FakeUserTag(String label) {
-    // Canonicalize by name.
-    var existingTag = _instances[label];
-    if (existingTag != null) {
-      return existingTag;
-    }
-    // Throw an exception if we've reached the maximum number of user tags.
-    if (_instances.length == UserTag.MAX_USER_TAGS) {
-      throw new UnsupportedError(
-          'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.');
-    }
-    // Create a new instance and add it to the instance map.
-    var instance = new _FakeUserTag.real(label);
-    _instances[label] = instance;
-    return instance;
-  }
-
-  final String label;
-
-  UserTag makeCurrent() {
-    var old = _currentTag;
-    _currentTag = this;
-    return old;
-  }
-
-  static final UserTag _defaultTag = new _FakeUserTag('Default');
-}
-
-var _currentTag = _FakeUserTag._defaultTag;
-
-/// Returns the current [UserTag] for the isolate.
-UserTag getCurrentTag() {
-  return _currentTag;
-}
-
-/// Abstract [Metric] class. Metric names must be unique, are hierarchical,
-/// and use periods as separators. For example, 'a.b.c'. Uniqueness is only
-/// enforced when a Metric is registered. The name of a metric cannot contain
-/// the slash ('/') character.
-abstract class Metric {
-  /// [name] of this metric.
-  final String name;
-  /// [description] of this metric.
-  final String description;
-
-  Metric(this.name, this.description) {
-    if ((name == 'vm') || name.contains('/')) {
-      throw new ArgumentError('Invalid Metric name.');
-    }
-
-  }
-
-  Map _toJSON();
-}
-
-/// A measured value with a min and max. Initial value is min. Value will
-/// be clamped to the interval [min, max].
-class Gauge extends Metric {
-  final double min;
-  final double max;
-
-  double _value;
-  double get value => _value;
-  set value(double v) {
-    if (v < min) {
-      v = min;
-    } else if (v > max) {
-      v = max;
-    }
-    _value = v;
-  }
-
-  Gauge(String name, String description, this.min, this.max)
-      : super(name, description) {
-    if (min is! double) {
-      throw new ArgumentError('min must be a double');
-    }
-    if (max is! double) {
-      throw new ArgumentError('max must be a double');
-    }
-    if (!(min < max)) {
-      throw new ArgumentError('min must be less than max');
-    }
-    _value = min;
-  }
-
-  Map _toJSON() {
-    var map = {
-      'type': 'Gauge',
-      'id': 'metrics/$name',
-      'name': name,
-      'description': description,
-      'value': value,
-      'min': min,
-      'max': max,
-    };
-    return map;
-  }
-}
-
-
-/// A changing value. Initial value is 0.0.
-class Counter extends Metric {
-  Counter(String name, String description)
-      : super(name, description);
-
-  double _value = 0.0;
-  double get value => _value;
-  set value(double v) {
-    _value = v;
-  }
-
-  Map _toJSON() {
-    var map = {
-      'type': 'Counter',
-      'id': 'metrics/$name',
-      'name': name,
-      'description': description,
-      'value': value,
-    };
-    return map;
-  }
-}
-
-class Metrics {
-  static final Map<String, Metric> _metrics = new Map<String, Metric>();
-
-  /// Register [Metric]s to make them visible to Observatory.
-  static void register(Metric metric) {
-    if (metric is! Metric) {
-      throw new ArgumentError('metric must be a Metric');
-    }
-    if (_metrics[metric.name] != null) {
-      throw new ArgumentError('Registered metrics have unique names');
-    }
-    _metrics[metric.name] = metric;
-  }
-
-  /// Deregister [Metric]s to make them not visible to Observatory.
-  static void deregister(Metric metric) {
-    if (metric is! Metric) {
-      throw new ArgumentError('metric must be a Metric');
-    }
-    _metrics.remove(metric.name);
-  }
-
-  static String _printMetric(String id) {
-    var metric = _metrics[id];
-    if (metric == null) {
-      return null;
-    }
-    return JSON.encode(metric._toJSON());
-  }
-
-  static String _printMetrics() {
-    var metrics = [];
-    for (var metric in _metrics.values) {
-      metrics.add(metric._toJSON());
-    }
-    var map = {
-      'type': 'MetricList',
-      'metrics': metrics,
-    };
-    return JSON.encode(map);
-  }
-}
+export 'dart:developer' show getCurrentTag,
+                             Counter,
+                             Gauge,
+                             Metric,
+                             Metrics,
+                             UserTag;
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index e2699d0..031698c 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -42,8 +42,6 @@
 Language/12_Expressions/12_Instance_Creation/1_New_A06_t15: CompileTimeError # Issue 21092
 Language/12_Expressions/12_Instance_Creation/2_Const_A11_t01: fail # Issue 21134 and co19 issue 714
 Language/12_Expressions/12_Instance_Creation/2_Const_A11_t03: fail # Issue 21134 and co19 issue 714
-Language/12_Expressions/22_Equality_A01_t01: fail # Issue 21137
-Language/12_Expressions/22_Equality_A05_t01: fail # Issue 21137
 Language/12_Expressions/30_Identifier_Reference_A02_t01: fail # Issue 21154
 Language/13_Statements/04_Local_Function_Declaration_A04_t01: MissingCompileTimeError # Issue 21050
 Language/13_Statements/04_Local_Function_Declaration_A04_t03: MissingCompileTimeError # Issue 21050
@@ -1464,11 +1462,21 @@
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: RuntimeError # Please triage this failure
 
 [ $compiler == dart2js && $runtime == chrome && ($system == windows || $system == macos) ]
-# New failures on Chrome 42, linux bots are not yet at that version.
+# New failures on Chrome 43, linux bots are not yet at that version.
+LayoutTests/fast/css/content-language-case-insensitivity_t01: RuntimeError # Issue 23506
+LayoutTests/fast/css/content-language-dynamically-removed_t01: RuntimeError # Issue 23506
+LayoutTests/fast/css/content-language-dynamically-added_t01: RuntimeError # Issue 23506
+LayoutTests/fast/css/content-language-no-content_t01: RuntimeError # Issue 23506
+LayoutTests/fast/css/content-language-multiple_t01: RuntimeError # Issue 23506
+LayoutTests/fast/css/content-language-mapped-to-webkit-locale_t01: RuntimeError # Issue 23506
+LayoutTests/fast/css/getComputedStyle/computed-style-properties_t01: RuntimeError # Issue 23506
+LayoutTests/fast/css/nested-at-rules_t01: RuntimeError # Issue 23506
 LayoutTests/fast/css/getComputedStyle/counterIncrement-without-counter_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/image-set-setting_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/parsing-text-rendering_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/background-shorthand-csstext_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/innerHTML/javascript-url_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-input-element/url_t01: RuntimeError # Please triage this failure
@@ -2719,7 +2727,6 @@
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-before-open-sync-request_t01: Pass, RuntimeError # Issue 23479. Unsuppress once bots are all updated.
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-before-open_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/4XPath/Borrowed/cz_20030217_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/4XPath/Borrowed/namespace-nodes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: RuntimeError # Please triage this failure
@@ -2788,7 +2795,6 @@
 LibTest/html/HttpRequest/request_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/HttpRequest/responseText_A01_t02: Skip # Times out. Please triage this failure
 LibTest/html/HttpRequest/responseType_A01_t01: RuntimeError # Please triage this failure
-LibTest/html/HttpRequest/responseType_A01_t02: RuntimeError # Please triage this failure
 LibTest/html/HttpRequest/setRequestHeader_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/HttpRequest/statusText_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/HttpRequest/status_A01_t01: RuntimeError # Please triage this failure
@@ -3126,6 +3132,8 @@
 LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-style_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/MutationObserver/observe-options-attributes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/MutationObserver/observe-options-character-data_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-before-open_t01: RuntimeError # Please triage this failure
+LibTest/html/HttpRequest/responseType_A01_t02: RuntimeError # Please triage this failure
 
 [ $compiler == dart2js && $runtime == safari ]
 Language/12_Expressions/00_Object_Identity/1_Object_Identity_A05_t02: RuntimeError # Please triage this failure
@@ -4206,7 +4214,7 @@
 WebPlatformTest/html/dom/elements/global-attributes/dataset-delete_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/dom/elements/global-attributes/dataset-get_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/dom/elements/global-attributes/dataset-set_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: Pass, RuntimeError # Fails on 7.1. Please triage this failure 
+WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: Pass, RuntimeError # Fails on 7.1. Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out. Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out. Please triage this failure
@@ -7835,6 +7843,7 @@
 LayoutTests/fast/canvas/canvas-scale-strokePath-shadow_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-set-properties-with-non-invertible-ctm_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-setTransform_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/canvas-strokePath-alpha-shadow_t01: Skip # Issue 23508
 LayoutTests/fast/canvas/canvas-to-canvas_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-toDataURL-crash_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-transforms-fillRect-shadow_t01: Pass, RuntimeError # Please triage this failure
@@ -9609,18 +9618,10 @@
 Language/03_Overview/1_Scoping_A01_t39: Crash # Instance of 'TypeOperator': type check unimplemented for f.
 Language/03_Overview/1_Scoping_A02_t19: Crash # (switch (1){case 1:var x;break;case 2:var x;break;}): Unhandled node
 Language/03_Overview/2_Privacy_A01_t06: Crash # Instance of 'TypeOperator': type check unimplemented for _inaccessibleFuncType.
-Language/05_Variables/05_Variables_A04_t01: Crash # unsupported element kind: foo:field
-Language/05_Variables/05_Variables_A14_t07: Crash # unsupported element kind: z2:field
-Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t01: Crash # unsupported element kind: c:field
-Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Crash # unsupported element kind: sFinalTyped:field
-Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t03: Crash # unsupported element kind: sFinalTyped:field
-Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t04: RuntimeError # Please triage this failure.
-Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: RuntimeError # Please triage this failure.
 Language/07_Classes/07_Classes_A02_t17: Crash # Please triage this failure.
 Language/07_Classes/07_Classes_A02_t18: Crash # Please triage this failure.
 Language/07_Classes/07_Classes_A02_t19: Crash # Please triage this failure.
 Language/07_Classes/1_Instance_Methods/2_Operators_A02_t06: Crash # Please triage this failure.
-Language/07_Classes/1_Instance_Methods/2_Operators_A02_t20: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t02: Crash # Please triage this failure.
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t03: Crash # Please triage this failure.
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t05: Crash # Please triage this failure.
@@ -9634,26 +9635,9 @@
 Language/07_Classes/6_Constructors/2_Factories_A09_t02: Crash # Please triage this failure.
 Language/07_Classes/6_Constructors/2_Factories_A09_t03: Crash # Please triage this failure.
 Language/07_Classes/6_Constructors/2_Factories_A09_t04: Crash # Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A14_t03: RuntimeError # Please triage this failure.
-Language/07_Classes/7_Static_Methods_A01_t02: RuntimeError # Please triage this failure.
 Language/10_Generics/09_Generics_A04_t03: Crash # Instance of 'TypeOperator': type check unimplemented for S.
 Language/10_Generics/10_Generics_A05_t01: Crash # Instance of 'TypeOperator': type check unimplemented for T.
 Language/10_Generics/10_Generics_A05_t03: Crash # Instance of 'TypeOperator': type check unimplemented for T.
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A01_t01: Crash # unsupported element kind: notNil:field
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A01_t02: Crash # unsupported element kind: false2:field
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A05_t01: Crash # unsupported element kind: o2:field
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A07_t01: Crash # unsupported element kind: n7:field
-Language/12_Expressions/01_Constants_A01_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/01_Constants_A02_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/01_Constants_A04_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/01_Constants_A07_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/01_Constants_A08_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/01_Constants_A09_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/01_Constants_A10_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/01_Constants_A13_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/01_Constants_A14_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/06_Lists_A08_t04: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
-Language/12_Expressions/07_Maps_A07_t04: Crash # Instance of 'TypeOperator': type check unimplemented for Map<String, int>.
 Language/12_Expressions/12_Instance_Creation/1_New_A06_t07: RuntimeError # Please triage this failure.
 Language/12_Expressions/12_Instance_Creation/1_New_A06_t08: Crash # Please triage this failure.
 Language/12_Expressions/12_Instance_Creation/1_New_A06_t09: RuntimeError # Please triage this failure.
@@ -9663,30 +9647,14 @@
 Language/12_Expressions/13_Property_Extraction_A03_t01: RuntimeError # Please triage this failure.
 Language/12_Expressions/13_Property_Extraction_A03_t02: RuntimeError # Please triage this failure.
 Language/12_Expressions/13_Property_Extraction_A03_t03: RuntimeError # Please triage this failure.
-Language/12_Expressions/13_Spawning_an_Isolate_A01_t01: Crash # unsupported element kind: _completer:field
-Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t05: Crash # unsupported element kind: f:field
-Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t13: Crash # unsupported element kind: test4:field
-Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t14: Crash # unsupported element kind: test4:field
 Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A01_t01: RuntimeError # Please triage this failure.
 Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: RuntimeError # Please triage this failure.
 Language/12_Expressions/20_Logical_Boolean_Expressions_A01_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/20_Logical_Boolean_Expressions_A06_t09: Crash # unsupported element kind: x:field
-Language/12_Expressions/20_Logical_Boolean_Expressions_A06_t10: Crash # unsupported element kind: x:field
 Language/12_Expressions/22_Equality_A03_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/30_Identifier_Reference_A08_t01: Crash # unsupported element kind: tlFinalTyped:field
-Language/12_Expressions/30_Identifier_Reference_A08_t02: Crash # unsupported element kind: tlFinalTyped:field
-Language/12_Expressions/30_Identifier_Reference_A08_t03: Crash # unsupported element kind: tlFinalTyped:field
 Language/12_Expressions/30_Identifier_Reference_A09_t03: Crash # (i=0): For-loop variable captured in loop header
-Language/12_Expressions/30_Identifier_Reference_A13_t01: Crash # unsupported element kind: x4:field
-Language/12_Expressions/32_Type_Test_A02_t01: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
 Language/12_Expressions/32_Type_Test_A02_t03: Crash # Instance of 'TypeOperator': type check unimplemented for Undeclared.
 Language/12_Expressions/32_Type_Test_A02_t04: Crash # Instance of 'TypeOperator': type check unimplemented for G<int, bool>.
-Language/12_Expressions/32_Type_Test_A02_t05: Crash # Instance of 'TypeOperator': type check unimplemented for G<int, bool>.
-Language/12_Expressions/32_Type_Test_A02_t06: Crash # Instance of 'TypeOperator': type check unimplemented for G<int, bool>.
 Language/12_Expressions/32_Type_Test_A02_t07: Crash # Instance of 'TypeOperator': type check unimplemented for G<Unknown>.
-Language/12_Expressions/32_Type_Test_A03_t01: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
-Language/12_Expressions/32_Type_Test_A07_t01: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
-Language/12_Expressions/32_Type_Test_A07_t02: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
 Language/12_Expressions/33_Type_Cast_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 Language/12_Expressions/33_Type_Cast_A01_t04: Crash # Instance of 'TypeOperator': type casts not implemented.
 Language/12_Expressions/33_Type_Cast_A02_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
@@ -9702,8 +9670,6 @@
 Language/12_Expressions/33_Type_Cast_A04_t02: Crash # Instance of 'TypeOperator': type casts not implemented.
 Language/12_Expressions/Expressions_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 Language/12_Expressions/Expressions_A01_t02: Crash # Instance of 'TypeOperator': type casts not implemented.
-Language/13_Statements/03_Variable_Declaration_A01_t14: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
-Language/13_Statements/03_Variable_Declaration_A01_t15: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
 Language/13_Statements/06_For_A01_t07: Crash # Please triage this failure.
 Language/13_Statements/09_Switch_A01_t01: Crash # (switch (1){case 0:case 1:}): Unhandled node
 Language/13_Statements/09_Switch_A01_t02: Crash # (switch (1){l1:l2:l3:case (1):}): Unhandled node
@@ -9728,7 +9694,7 @@
 Language/13_Statements/11_Try_A03_t01: Crash # Instance of 'TypeOperator': type check unimplemented for Unavailable.
 Language/13_Statements/11_Try_A03_t02: Crash # Instance of 'TypeOperator': type check unimplemented for Unavailable.
 Language/13_Statements/11_Try_A03_t03: Crash # Instance of 'TypeOperator': type check unimplemented for Foo.
-Language/13_Statements/11_Try_A03_t04: Crash # unsupported element kind: error:field
+Language/13_Statements/11_Try_A03_t04: Crash # Instance of 'TypeOperator': type check unimplemented for Unavailable.
 Language/13_Statements/11_Try_A07_t02: Crash # (try {throw ex;}on int catch (i){}on bool catch (b){}finally {isFinallyExecuted=true;}): try/finally
 Language/13_Statements/11_Try_A08_t01: Crash #  try/finally
 Language/13_Statements/11_Try_A09_t01: Crash #  try/finally
@@ -9760,20 +9726,6 @@
 Language/13_Statements/14_Continue_A03_t06: Crash #  try/finally
 Language/13_Statements/14_Continue_A03_t07: Crash #  try/finally
 Language/14_Libraries_and_Scripts/13_Libraries_and_Scripts_A05_t02: Crash # Instance of 'TypeOperator': type check unimplemented for _td.
-Language/14_Libraries_and_Scripts/13_Libraries_and_Scripts_A06_t01: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A01_t39: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A01_t40: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A01_t49: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t01: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t02: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t11: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t14: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t16: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t17: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t18: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t20: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t21: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t22: RuntimeError # Please triage this failure.
 Language/14_Libraries_and_Scripts/1_Imports_A02_t26: Crash # Instance of 'TypeOperator': type check unimplemented for prefix.
 Language/14_Libraries_and_Scripts/1_Imports_A02_t27: Crash # Instance of 'TypeOperator': type check unimplemented for bar.
 Language/14_Libraries_and_Scripts/1_Imports_A02_t28: Crash # Instance of 'TypeOperator': type check unimplemented for bar.
@@ -9788,18 +9740,8 @@
 Language/14_Libraries_and_Scripts/1_Imports_A03_t45: Crash # Instance of 'TypeOperator': type casts not implemented.
 Language/14_Libraries_and_Scripts/1_Imports_A03_t64: Crash # Instance of 'TypeOperator': type casts not implemented.
 Language/14_Libraries_and_Scripts/1_Imports_A03_t65: Crash # Instance of 'TypeOperator': type casts not implemented.
-Language/14_Libraries_and_Scripts/1_Imports_A06_t01: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/1_Imports_A06_t02: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/2_Exports_A03_t01: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/2_Exports_A03_t02: RuntimeError # Please triage this failure.
 Language/14_Libraries_and_Scripts/2_Exports_A04_t03: Crash # Instance of 'TypeOperator': type check unimplemented for foo.
 Language/14_Libraries_and_Scripts/2_Exports_A06_t02: Crash # Instance of 'TypeOperator': type check unimplemented for foo.
-Language/14_Libraries_and_Scripts/2_Exports_A08_t01: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A02_t03: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A02_t04: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A03_t01: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A03_t11: RuntimeError # Please triage this failure.
-Language/14_Libraries_and_Scripts/3_Parts_A04_t01: RuntimeError # Please triage this failure.
 Language/15_Types/1_Static_Types_A03_t01: Crash # Instance of 'TypeOperator': type check unimplemented for UnknownType.
 Language/15_Types/3_Type_Declarations/1_Typedef_A01_t03: Crash # Instance of 'TypeOperator': type check unimplemented for f.
 Language/15_Types/3_Type_Declarations/1_Typedef_A02_t01: Crash # Instance of 'TypeOperator': type check unimplemented for f_t.
@@ -9811,31 +9753,14 @@
 Language/15_Types/3_Type_Declarations/1_Typedef_A07_t05: Crash # Instance of 'TypeOperator': type check unimplemented for f.
 Language/15_Types/3_Type_Declarations/1_Typedef_A07_t06: Crash # Instance of 'TypeOperator': type check unimplemented for f.
 Language/15_Types/3_Type_Declarations/1_Typedef_A07_t07: Crash # Instance of 'TypeOperator': type check unimplemented for f.
-Language/15_Types/4_Interface_Types_A05_t02: Crash # Instance of 'TypeOperator': type check unimplemented for A<int>.
-Language/15_Types/4_Interface_Types_A05_t03: Crash # Instance of 'TypeOperator': type check unimplemented for A<int, double, A>.
 Language/15_Types/4_Interface_Types_A05_t04: Crash # Please triage this failure.
-Language/15_Types/4_Interface_Types_A06_t02: Crash # Instance of 'TypeOperator': type check unimplemented for List<double>.
-Language/15_Types/4_Interface_Types_A07_t01: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
-Language/15_Types/4_Interface_Types_A07_t02: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
 Language/15_Types/4_Interface_Types_A08_t01: Crash # Instance of 'TypeOperator': type check unimplemented for S.
-Language/15_Types/4_Interface_Types_A08_t04: Crash # Instance of 'TypeOperator': type check unimplemented for G<int>.
-Language/15_Types/4_Interface_Types_A08_t05: Crash # Instance of 'TypeOperator': type check unimplemented for G<int>.
-Language/15_Types/4_Interface_Types_A08_t06: Crash # Instance of 'TypeOperator': type check unimplemented for IManyArgs<int, G, G, G, double>.
-Language/15_Types/4_Interface_Types_A10_t01: Crash # Instance of 'TypeOperator': type check unimplemented for List<String>.
-Language/15_Types/4_Interface_Types_A10_t02: Crash # Instance of 'TypeOperator': type check unimplemented for Checker_Object<Object>.
-Language/15_Types/4_Interface_Types_A10_t03: Crash # Instance of 'TypeOperator': type check unimplemented for Checker_I<I>.
 Language/15_Types/4_Interface_Types_A10_t04: Crash # Please triage this failure.
 Language/15_Types/4_Interface_Types_A10_t06: Crash # Please triage this failure.
 Language/15_Types/4_Interface_Types_A10_t07: Crash # Please triage this failure.
 Language/15_Types/4_Interface_Types_A10_t08: Crash # Please triage this failure.
 Language/15_Types/4_Interface_Types_A10_t09: Crash # Please triage this failure.
-Language/15_Types/4_Interface_Types_A11_t03: Crash # Instance of 'TypeOperator': type check unimplemented for I<num>.
 Language/15_Types/4_Interface_Types_A11_t04: Crash # Instance of 'TypeOperator': type check unimplemented for S<int>.
-Language/15_Types/4_Interface_Types_A12_t09: Crash # Instance of 'TypeOperator': type check unimplemented for List<String>.
-Language/15_Types/4_Interface_Types_A12_t12: Crash # Instance of 'TypeOperator': type check unimplemented for G<B, B, B, B>.
-Language/15_Types/4_Interface_Types_A12_t13: Crash # Instance of 'TypeOperator': type check unimplemented for G<C>.
-Language/15_Types/4_Interface_Types_A12_t14: Crash # Instance of 'TypeOperator': type check unimplemented for A<double>.
-Language/15_Types/4_Interface_Types_A12_t16: Crash # Instance of 'TypeOperator': type check unimplemented for A<int, int, double, int>.
 Language/15_Types/4_Interface_Types_A12_t18: Crash # Instance of 'TypeOperator': type check unimplemented for F1.
 Language/15_Types/5_Function_Types_A01_t01: Crash # Instance of 'TypeOperator': type check unimplemented for check_t.
 Language/15_Types/5_Function_Types_A01_t02: Crash # Instance of 'TypeOperator': type check unimplemented for t1.
@@ -9874,481 +9799,35 @@
 Language/15_Types/5_Function_Types_A06_t01: Crash # Instance of 'TypeOperator': type check unimplemented for f.
 Language/15_Types/6_Type_dynamic_A02_t01: Crash # Instance of 'TypeOperator': type check unimplemented for S.
 Language/15_Types/8_Parameterized_Types_A03_t06: Crash # Instance of 'TypeOperator': type check unimplemented for T1.
-Language/16_Reference/1_Lexical_Rules_A01_t10: Crash # unsupported element kind: characters:field
-LayoutTests/fast/animation/request-animation-frame-cancel2_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/animation/request-animation-frame-cancel_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/animation/request-animation-frame-prefix_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/animation/request-animation-frame-timestamps-advance_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/animation/request-animation-frame-timestamps_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/animation/request-animation-frame-within-callback_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/backgrounds/001_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/backgrounds/animated-gif-as-background_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/backgrounds/multiple-backgrounds-assert_t01: Crash # unsupported element kind: _asyncCounter:field
 LayoutTests/fast/backgrounds/multiple-backgrounds-computed-style_t01: Crash #  Unhandled node
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.negative_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.veryLarge_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.verySmall_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/DrawImageSinglePixelStretch_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-as-image-incremental-repaint_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-before-css_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-clipping_t01: Crash # unsupported element kind: nonSeparateBlendModes:field
-LayoutTests/fast/canvas/canvas-blending-color-over-color_t01: Crash # unsupported element kind: nonSeparateBlendModes:field
-LayoutTests/fast/canvas/canvas-blending-color-over-gradient_t01: Crash # unsupported element kind: nonSeparateBlendModes:field
-LayoutTests/fast/canvas/canvas-blending-color-over-image_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-color-over-pattern_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-fill-style_t01: Crash # unsupported element kind: nonSeparateBlendModes:field
-LayoutTests/fast/canvas/canvas-blending-global-alpha_t01: Crash # unsupported element kind: nonSeparateBlendModes:field
-LayoutTests/fast/canvas/canvas-blending-gradient-over-color_t01: Crash # unsupported element kind: nonSeparateBlendModes:field
-LayoutTests/fast/canvas/canvas-blending-gradient-over-gradient_t01: Crash # unsupported element kind: nonSeparateBlendModes:field
-LayoutTests/fast/canvas/canvas-blending-gradient-over-image_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-gradient-over-pattern_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-image-over-color_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-image-over-gradient_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-image-over-image_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-image-over-pattern_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-pattern-over-color_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-pattern-over-gradient_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-pattern-over-image_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-pattern-over-pattern_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-blending-shadow_t01: Crash # unsupported element kind: nonSeparateBlendModes:field
-LayoutTests/fast/canvas/canvas-blending-text_t01: Crash # unsupported element kind: nonSeparateBlendModes:field
-LayoutTests/fast/canvas/canvas-blending-transforms_t01: Crash # unsupported element kind: nonSeparateBlendModes:field
-LayoutTests/fast/canvas/canvas-composite-alpha_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-composite-canvas_t01: Crash # unsupported element kind: compositeTypes:field
-LayoutTests/fast/canvas/canvas-composite-image_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-composite-stroke-alpha_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-css-crazy_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-imageSmoothingEnabled-repaint_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-lose-restore-googol-size_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/canvas/canvas-lose-restore-max-int-size_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/canvas/canvas-resize-after-paint_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/canvas-scale-drawImage-shadow_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/drawImage-with-broken-image_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/drawImage-with-valid-image_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/setWidthResetAfterForcedRender_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/attrib-location-length-limits_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/canvas-2d-webgl-texture_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/canvas/webgl/canvas-test_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/canvas-zero-size_t01: Crash # unsupported element kind: error:field
 LayoutTests/fast/canvas/webgl/compressed-tex-image_t01: Crash # Please triage this failure.
-LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/context-lost-restored_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/context-lost_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/css-webkit-canvas-repaint_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: Crash # unsupported element kind: requestAnimFrame:field
 LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: Crash # Please triage this failure.
-LayoutTests/fast/canvas/webgl/functions-returning-strings_t01: Crash # Instance of 'TypeOperator': type check unimplemented for List<String>.
-LayoutTests/fast/canvas/webgl/gl-enable-enum-test_t01: Crash # unsupported element kind: desktopGL:field
-LayoutTests/fast/canvas/webgl/gl-enum-tests_t01: Crash # unsupported element kind: desktopGL:field
-LayoutTests/fast/canvas/webgl/gl-teximage_t01: Crash # unsupported element kind: _asyncCounter:field
 LayoutTests/fast/canvas/webgl/gl-uniformmatrix4fv_t01: Crash #  Unhandled node
-LayoutTests/fast/canvas/webgl/gl-vertex-attrib-zero-issues_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/glsl-conformance_t01: Crash # unsupported element kind: error:field
 LayoutTests/fast/canvas/webgl/index-validation_t01: Crash #  Unhandled node
-LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: Crash # unsupported element kind: desktopGL:field
-LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: Crash # unsupported element kind: _completer:field
+LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Crash #  Unhandled node
 LayoutTests/fast/canvas/webgl/read-pixels-pack-alignment_t01: Crash #  Unhandled node
-LayoutTests/fast/canvas/webgl/read-pixels-test_t01: Crash # unsupported element kind: _completer:field
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: Crash #  Unhandled node
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/tex-image-webgl_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/texture-bindings-uneffected-on-resize_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/texture-color-profile_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/canvas/webgl/texture-npot_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/uniform-location-length-limits_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/webgl-composite-modes-repaint_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/webgl-composite-modes_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/webgl-large-texture_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/webgl-layer-update_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/webgl-specific_t01: Crash # unsupported element kind: error:field
-LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/canvas/webgl/webgl-viewport-parameters-preserved_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-generated-content/bug91547_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-generated-content/float-first-letter-siblings-convert-to-inline_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-generated-content/inline-splitting-with-after-float-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-generated-content/pseudo-animation-display_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-generated-content/pseudo-animation_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-generated-content/pseudo-transition_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-grid-layout/auto-content-resolution-rows_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/breadth-size-resolution-grid_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/calc-resolution-grid-item_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/display-grid-set-get_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/flex-and-minmax-content-resolution-rows_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/flex-content-resolution-columns_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/flex-content-resolution-rows_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-auto-columns-rows-get-set_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-auto-flow-get-set_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-auto-flow-update_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-grid-layout/grid-element-bad-cast-addchild_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-element-border-grid-item_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-element-border-padding-grid-item_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-element-empty-row-column_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-element-min-max-height_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-element-padding-grid-item_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-element-padding-margin_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-element-remove-svg-child_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-element-shrink-to-fit_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-item-area-get-set_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-item-bad-named-area-auto-placement_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-item-bad-resolution-double-span_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-grid-layout/grid-item-display_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-horiz-bt_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-lr_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-rl_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-item-margin-resolution_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-item-order-auto-flow-resolution_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-strict-ordering-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/grid-template-areas-get-set_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/implicit-rows-auto-resolution_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/justify-self-cell_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/minmax-fixed-logical-height-only_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/minmax-fixed-logical-width-only_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-update_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item-update_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-absolutes_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-blocks_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-column-flex-items_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-flex-items_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-intrinsic-dimensions/multicol_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-intrinsic-dimensions/tables_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/attribute-selector-begin-dynamic-no-elementstyle_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/cached-sheet-restore-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/comment-before-charset-external_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/comment-before-charset_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/content/content-none_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/content/content-normal_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/content/content-quotes-01_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/content/content-quotes-02_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/content/content-quotes-03_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/content/content-quotes-04_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/content/content-quotes-05_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/content/content-quotes-06_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/counters/asterisk-counter-update-after-layout-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/counters/complex-before_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/counters/counter-before-selector-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/counters/counter-reparent-table-children-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/counters/counter-reset-subtree-insert-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/counters/counter-ruby-text-cleared_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/counters/counter-traverse-object-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/crash-on-incomplete-not_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/css-keyframe-style-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/device-aspect-ratio_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/first-letter-inline-flow-split-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/first-letter-inline-flow-split-table-crash_t01: Crash # unsupported element kind: _completer:field
+LayoutTests/fast/css/css-keyframe-style-crash_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/css/first-line-parent-style-different_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/css/focus-display-block-inline_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/font-face-cache-bug_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/font-face-insert-link_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/font-face-svg-decoding-error_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/font-face-unicode-range-load_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/font-face-used-after-retired_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/fontfaceset-download-error_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/fontfaceset-events_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/fontfaceset-loadingdone_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/implicit-attach-marking_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/link-alternate-stylesheet-1_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/link-alternate-stylesheet-2_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/link-alternate-stylesheet-3_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/link-alternate-stylesheet-4_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/link-alternate-stylesheet-5_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/link-disabled-attr-parser_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/max-device-aspect-ratio_t01: Crash # unsupported element kind: _completer:field
 LayoutTests/fast/css/media-rule-dyn_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/css/min-device-aspect-ratio_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/nested-at-rules_t01: Crash # unsupported element kind: _completer:field
 LayoutTests/fast/css/parsing-css-allowed-string-characters_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/css/parsing-css-comment_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/css/parsing-css-escapes_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/css/parsing-css-nonascii_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/css/parsing-css-nth-child_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/css/parsing-css-surrogate-pairs_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/css/percent-min-width-img-src-change_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/percent-width-img-src-change_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/positioned-in-relative-position-inline-crash_t01: Crash # unsupported element kind: _completer:field
 LayoutTests/fast/css/pseudo-out-of-range_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Crash # unsupported element kind: _asyncCounter:field
 LayoutTests/fast/css/pseudo-valid-dynamic_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/css/readonly-pseudoclass-opera-005_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/css/relative-position-replaced-in-table-display-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/relative-positioned-block-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/remove-fixed-resizer-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/shadow-current-color_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/sheet-collection-link_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/sheet-title_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/space-before-charset-external_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/space-before-charset_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/sticky/remove-inline-sticky-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/sticky/remove-sticky-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/sticky/sticky-table-col-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/style-element-process-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/style-scoped/style-scoped-shadow-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/css/stylesheet-enable-first-alternate-link_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-link_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/stylesheet-parentStyleSheet_t01: Crash # unsupported element kind: _asyncCounter:field
 LayoutTests/fast/css/visited-link-hang_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/css/webkit-keyframes-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/css/webkit-marquee-speed-unit-in-quirksmode_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLAnchorElement/remove-href-from-focused-anchor_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLDialogElement/submit-dialog-close-event_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLDocument/active-element-gets-unforcusable_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLFormElement/move-option-between-documents_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLImageElement/image-loading-gc_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLImageElement/image-natural-width-height_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLImageElement/image-src-absolute-url_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test-nonexistent_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLLinkElement/link-onerror-stylesheet-with-existent-and-non-existent-import_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLLinkElement/link-onerror-stylesheet-with-non-existent-import_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLLinkElement/link-onerror_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLLinkElement/link-onload-before-page-load_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLLinkElement/link-onload-stylesheet-with-import_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLLinkElement/link-onload2_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLLinkElement/link-onload_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLLinkElement/onload-completion-test_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLLinkElement/prefetch-onerror_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLLinkElement/prefetch-onload_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLObjectElement/children-changed_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLProgressElement/progress-element-with-style-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLScriptElement/defer-script-invalid-url_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLScriptElement/dont-load-unknown-type_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLScriptElement/isURLAttribute_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLScriptElement/remove-source_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLScriptElement/script-for-attribute-unexpected-execution_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLScriptElement/script-load-events_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLScriptElement/script-reexecution_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/HTMLStyleElement/programmatically-add-style-with-onerror-handler_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLStyleElement/programmatically-add-style-with-onload-handler_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLStyleElement/style-onerror-with-existent-and-non-existent-import_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLStyleElement/style-onerror_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLStyleElement/style-onload-before-page-load_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLStyleElement/style-onload2_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLStyleElement/style-onload_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/HTMLTemplateElement/innerHTML-inert_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/MutationObserver/callback-arguments_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/clear-transient-without-delivery_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/create-during-delivery_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/cross-document_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/database-callback-delivery_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/delivery-order_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/disconnect-cancel-pending_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/document-fragment-insertion_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/mutate-during-delivery_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/observe-attributes_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/observe-characterdata_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/observe-childList_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/observe-subtree_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/observer-wrapper-dropoff-transient_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/MutationObserver/observer-wrapper-dropoff_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/MutationObserver/takeRecords_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/MutationObserver/transient-gc-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/SelectorAPI/bug-17313_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/StyleSheet/detached-style-2_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/StyleSheet/detached-style_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Crash # unsupported element kind: _completer:field
 LayoutTests/fast/dom/TreeWalker/TreeWalker-basic_t01: Crash # Please triage this failure.
-LayoutTests/fast/dom/Window/getMatchedCSSRules-nested-rules_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/Window/getMatchedCSSRules-parent-stylesheets_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/css-cached-import-rule_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/css-delete-doc_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/css-insert-import-rule-twice_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/css-insert-import-rule_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/css-mediarule-deleteRule-update_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/css-mediarule-insertRule-update_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/cssTarget-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/custom/attribute-changed-callback_t01: Crash # unsupported element kind: attributeChangedCallback:field
-LayoutTests/fast/dom/custom/constructor-calls-created-synchronously_t01: Crash # unsupported element kind: attributeChangedCallback:field
-LayoutTests/fast/dom/custom/created-callback_t01: Crash # unsupported element kind: createdCallback:field
-LayoutTests/fast/dom/custom/document-register-on-create-callback_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/custom/element-type_t01: Crash # unsupported element kind: createdCallback:field
-LayoutTests/fast/dom/custom/element-upgrade_t01: Crash # unsupported element kind: createdCallback:field
-LayoutTests/fast/dom/document-set-title-mutations_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/domtimestamp-is-number_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/empty-hash-and-search_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/gc-image-element-2_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/gc-image-element_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/icon-url-change_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/icon-url-list_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/id-attribute-with-namespace-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/image-object_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/inner-text_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/location-hash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/non-styled-element-id-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/onerror-img_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/partial-layout-non-overlay-scrollbars_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/remove-body-during-body-replacement_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/content-pseudo-element-dynamic-attribute-change_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/insertion-point-list-menu-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/insertion-point-video-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/link-in-shadow-tree_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/nested-reprojection-inconsistent_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/pseudoclass-update-checked-option_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-optgroup_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-option_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-optgroup_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/remove-and-insert-style_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shadow/shadowroot-keyframes_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/shared-inline-style-after-node-removal_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/subtree-modified-attributes_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/dom/text-node-attach-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/vertical-scrollbar-in-rtl-doesnt-fire-onscroll_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dom/vertical-scrollbar-when-dir-change_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/dynamic/continuation-detach-crash_t01: Crash # unsupported element kind: _completer:field
+LayoutTests/fast/dom/location-hash_t01: Crash #  Unhandled node
 LayoutTests/fast/dynamic/inline-to-block-crash_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/dynamic/jQuery-animation-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/encoding/css-charset-dom_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/events/add-event-without-document_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/clipboard-clearData_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/defaultprevented_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/events/dispatch-event-being-dispatched_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/events/dispatch-event-no-document_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/document-elementFromPoint_t01: Crash # unsupported element kind: _completer:field
+LayoutTests/fast/encoding/css-charset-dom_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/events/event-attributes-after-exception_t01: Crash #  try/finally
-LayoutTests/fast/events/event-on-xhr-document_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/fire-scroll-event-element_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/fire-scroll-event_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/nested-event-remove-node-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/events/no-window-load_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/onerror-bubbling_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/onerror-img-after-gc_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/overflowchanged-event-raf-timing_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/scroll-during-zoom-change_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/scroll-event-does-not-bubble_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/scroll-event-phase_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/tabindex-removal-from-focused-element_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/window-load-capture_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/events/xhr-onclick-crash_t01: Crash # unsupported element kind: _completer:field
 LayoutTests/fast/eventsource/eventsource-constructor_t01: Crash # Please triage this failure.
-LayoutTests/fast/files/blob-close-read_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/files/blob-close-revoke_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/files/blob-parts-slice-test_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/files/blob-slice-test_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/files/file-reader-abort-in-last-progress_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/files/file-reader-done-reading-abort_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/files/file-reader-fffd_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/files/file-reader-immediate-abort_t01: Crash # unsupported element kind: _completer:field
 LayoutTests/fast/files/file-reader-methods-illegal-arguments_t01: Crash #  Unhandled node
-LayoutTests/fast/files/file-reader-readystate_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/files/file-reader-result-twice_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/files/read-blob-as-array-buffer_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/files/workers/inline-worker-via-blob-url_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/files/xhr-response-blob_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/async-operations_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/directory-entry-to-uri_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-after-reload-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-entry-to-uri_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-from-file-entry_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-metadata-after-write_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-writer-abort-continue_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-writer-abort-depth_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-writer-abort_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-writer-empty-blob_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-writer-events_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-writer-gc-blob_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-writer-truncate-extend_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/file-writer-write-overlapped_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/filesystem-reference_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/filesystem-unserializable_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/op-copy_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/op-get-entry_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/op-get-metadata_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/op-get-parent_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/op-move_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/op-read-directory_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/op-remove_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/op-restricted-chars_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/op-restricted-names_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/op-restricted-unicode_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/read-directory-many_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/read-directory_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/simple-readonly-file-object_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/simple-readonly_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/simple-required-arguments-getdirectory_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/simple-required-arguments-getfile_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/simple-temporary_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/filesystem/snapshot-file-with-gc_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/flexbox/crash-flexbox-no-layout-child_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/flexbox/layoutHorizontalBox-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/flexbox/overhanging-floats-not-removed-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/HTMLOptionElement_selected_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/activate-and-disabled-elements_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/autofocus-focus-only-once_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/autofocus-opera-004_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/autofocus-opera-005_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/autofocus-opera-007_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/button-click-DOM_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/button/button-disabled-blur_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/checkbox-onchange_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/dangling-form-element-crash_t01: Crash # unsupported element kind: _completer:field
+LayoutTests/fast/forms/autofocus-focus-only-once_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/forms/datalist/datalist-child-validation_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/forms/datalist/datalist_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/forms/date/date-interactive-validation-required_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
@@ -10356,109 +9835,36 @@
 LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/forms/datetimelocal/datetimelocal-pseudo-classes_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/forms/fieldset/fieldset-elements_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/forms/focus-style-pending_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/form-added-to-table_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/form-associated-element-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/form-submission-create-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/image/image-error-event-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/image/image-error-event-modifies-type-crash_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/input-type-change_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/input-width-height-attributes-without-renderer-loaded-image_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/input-width-height-attributes-without-renderer_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/interactive-validation-assertion-by-validate-twice_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/interactive-validation-attach-assertion_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/interactive-validation-select-crash_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/listbox-scroll-after-options-removed_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/menulist-disabled-selected-option_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/menulist-submit-without-selection_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/search-placeholder-value-changed_t01: Crash # unsupported element kind: _completer:field
 LayoutTests/fast/forms/search-popup-crasher_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/forms/select-change-listbox-to-popup-roundtrip_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/select-change-popup-to-listbox-in-event-handler_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/select-change-popup-to-listbox-roundtrip_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/select-generated-content_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/textarea-placeholder-relayout-assertion_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/forms/textarea-scrollbar-height_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/forms/textfield-focus-out_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/html/details-add-child-1_t01: Crash # unsupported element kind: createNewElement:field
-LayoutTests/fast/html/details-add-child-2_t01: Crash # unsupported element kind: createNewElement:field
-LayoutTests/fast/html/details-add-details-child-1_t01: Crash # unsupported element kind: createNewElement:field
-LayoutTests/fast/html/details-add-details-child-2_t01: Crash # unsupported element kind: createNewElement:field
-LayoutTests/fast/html/imports/import-element-removed-flag_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/innerHTML/innerHTML-special-elements_t01: Crash # unsupported element kind: outerTests:field
-LayoutTests/fast/loader/about-blank-hash-change_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/loader/about-blank-hash-kept_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/loader/hashchange-event-async_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/loader/hashchange-event-properties_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/loader/local-css-allowed-in-strict-mode_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/loader/onhashchange-attribute-listeners_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/loader/onload-policy-ignore-for-frame_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/loader/scroll-position-restored-on-back_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: Crash # unsupported element kind: _completer:field
+LayoutTests/fast/loader/hashchange-event-properties_t01: Crash #  Unhandled node
 LayoutTests/fast/media/media-query-list-syntax_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/mediastream/getusermedia_t01: Crash # unsupported element kind: navigator:field
-LayoutTests/fast/multicol/columns-shorthand-parsing_t02: Crash # unsupported element kind: tests:field
-LayoutTests/fast/multicol/float-truncation_t01: Crash # unsupported element kind: tests:field
+LayoutTests/fast/mediastream/getusermedia_t01: Crash # Please triage this failure.
 LayoutTests/fast/multicol/hit-test-above-or-below_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: Crash # unsupported element kind: tests:field
-LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: Crash # unsupported element kind: tests:field
-LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: Crash # unsupported element kind: tests:field
-LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: Crash # unsupported element kind: tests:field
-LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: Crash # unsupported element kind: tests:field
-LayoutTests/fast/overflow/scroll-vertical-not-horizontal_t01: Crash # unsupported element kind: _asyncCounter:field
 LayoutTests/fast/parser/parse-wbr_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/replaced/table-percent-height-text-controls_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/replaced/table-percent-height_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/replaced/table-percent-width_t01: Crash # unsupported element kind: _completer:field
 LayoutTests/fast/replaced/table-replaced-element_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/scrolling/scroll-element-into-view_t01: Crash # unsupported element kind: container:field
 LayoutTests/fast/selectors/style-sharing-last-child_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/shapes/parsing/parsing-shape-margin_t01: Crash # unsupported element kind: invalidShapeLengths:field
-LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: Crash # unsupported element kind: invalidShapeValues:field
-LayoutTests/fast/speechsynthesis/speech-synthesis-boundary-events_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/speechsynthesis/speech-synthesis-cancel_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/speechsynthesis/speech-synthesis-pause-resume_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/speechsynthesis/speech-synthesis-speak_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/speechsynthesis/speech-synthesis-utterance-uses-voice_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/sub-pixel/float-list-inside_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/svg/getbbox_t01: Crash # unsupported element kind: epsilon:field
+LayoutTests/fast/svg/getbbox_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/svg/tabindex-focus_t01: Crash #  try/finally
 LayoutTests/fast/svg/whitespace-angle_t01: Crash #  try/finally
 LayoutTests/fast/svg/whitespace-integer_t01: Crash #  try/finally
-LayoutTests/fast/svg/whitespace-length-invalid_t01: Crash # unsupported element kind: EPSILON:field
-LayoutTests/fast/svg/whitespace-length_t01: Crash # unsupported element kind: EPSILON:field
-LayoutTests/fast/svg/whitespace-number_t01: Crash # unsupported element kind: EPSILON:field
+LayoutTests/fast/svg/whitespace-length-invalid_t01: Crash #  try/finally
+LayoutTests/fast/svg/whitespace-length_t01: Crash #  try/finally
+LayoutTests/fast/svg/whitespace-number_t01: Crash #  try/finally
 LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: Crash #  Unhandled node
 LayoutTests/fast/table/hittest-tablecell-right-edge_t01: Crash #  Unhandled node
 LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: Crash #  Unhandled node
 LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge_t01: Crash #  Unhandled node
 LayoutTests/fast/table/incorrect-colgroup-span-values_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/table/min-width-css-block-table_t01: Crash # unsupported element kind: logicalWidthsCombinations:field
-LayoutTests/fast/table/min-width-css-inline-table_t01: Crash # unsupported element kind: logicalWidthsCombinations:field
-LayoutTests/fast/table/min-width-html-block-table_t01: Crash # unsupported element kind: logicalWidthsCombinations:field
-LayoutTests/fast/table/min-width-html-inline-table_t01: Crash # unsupported element kind: logicalWidthsCombinations:field
-LayoutTests/fast/table/prepend-in-anonymous-table_t01: Crash # unsupported element kind: childTypes:field
 LayoutTests/fast/table/rowindex-comment-nodes_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/text/find-backwards_t01: Crash # unsupported element kind: selection:field
-LayoutTests/fast/text/find-quotes_t01: Crash # unsupported element kind: rightDoubleQuotationMark:field
 LayoutTests/fast/text/font-ligature-letter-spacing_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/text/ipa-tone-letters_t01: Crash # unsupported element kind: testStrings:field
-LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: Crash # unsupported element kind: expected:field
-LayoutTests/fast/tokenizer/entities_t01: Crash # unsupported element kind: characters:field
-LayoutTests/fast/tokenizer/entities_t02: Crash # unsupported element kind: characters:field
-LayoutTests/fast/tokenizer/entities_t03: Crash # unsupported element kind: characters:field
-LayoutTests/fast/url/anchor_t01: Crash # unsupported element kind: cases:field
-LayoutTests/fast/url/file-http-base_t01: Crash # unsupported element kind: cases:field
-LayoutTests/fast/url/file_t01: Crash # unsupported element kind: cases:field
-LayoutTests/fast/url/host-lowercase-per-scheme_t01: Crash # unsupported element kind: urlExpectationsUppercase:field
-LayoutTests/fast/url/host_t01: Crash # unsupported element kind: cases:field
-LayoutTests/fast/url/idna2003_t01: Crash # unsupported element kind: cases:field
-LayoutTests/fast/url/idna2008_t01: Crash # unsupported element kind: cases:field
-LayoutTests/fast/url/invalid-urls-utf8_t01: Crash # unsupported element kind: testSet:field
+LayoutTests/fast/url/anchor_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
+LayoutTests/fast/url/file-http-base_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
+LayoutTests/fast/url/file_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
+LayoutTests/fast/url/host-lowercase-per-scheme_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
+LayoutTests/fast/url/host_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
+LayoutTests/fast/url/idna2003_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
+LayoutTests/fast/url/idna2008_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
+LayoutTests/fast/url/invalid-urls-utf8_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/url/ipv4_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/url/ipv6_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/url/mailto_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
@@ -10469,300 +9875,31 @@
 LayoutTests/fast/url/relative-unix_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/url/relative-win_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/url/relative_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/url/safari-extension_t01: Crash # unsupported element kind: safariExtensionTestSet:field
+LayoutTests/fast/url/safari-extension_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/url/scheme_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/url/segments-from-data-url_t01: Crash # unsupported element kind: cases:field
-LayoutTests/fast/url/segments_t01: Crash # unsupported element kind: cases:field
+LayoutTests/fast/url/segments-from-data-url_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
+LayoutTests/fast/url/segments_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/url/standard-url_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/url/trivial-segments_t01: Crash # unsupported element kind: cases:field
+LayoutTests/fast/url/trivial-segments_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/url/trivial_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/writing-mode/broken-ideographic-font_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/writing-mode/percentage-margins-absolute_t01: Crash # unsupported element kind: expectedProperties:field
-LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/xmlhttprequest/null-document-xmlhttprequest-open_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-get_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-html-response-encoding_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-html-document-responsetype-quirks_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-html-no-responsetype_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-invalid-xml_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-document-responsetype_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-text-responsetype_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-document_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-set-at-headers-received_t01: Crash # unsupported element kind: _completer:field
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-text_t01: Crash # unsupported element kind: _asyncCounter:field
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: Crash # unsupported element kind: LCHILD2:field
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: Crash # unsupported element kind: CHILD1:field
-LayoutTests/fast/xpath/4XPath/Core/test_location_path_t01: Crash # unsupported element kind: LCHILDREN:field
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: Crash # unsupported element kind: PI2:field
-LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: Crash # unsupported element kind: CHILD3:field
-LayoutTests/fast/xpath/4XPath/Core/test_nodeset_expr_t01: Crash # unsupported element kind: CHILD1:field
-LayoutTests/fast/xpath/4XPath/Core/test_numeric_expr_t01: Crash # unsupported element kind: CHILD1:field
-LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: Crash # unsupported element kind: ROOT:field
-LayoutTests/fast/xpath/4XPath/Core/test_predicate_list_t01: Crash # unsupported element kind: ROOT:field
-LayoutTests/fast/xpath/4XPath/Core/test_step_t01: Crash # unsupported element kind: GCHILD11:field
 LayoutTests/fast/xpath/name-null-namespace_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/xsl/default-html_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LayoutTests/fast/xsl/extra-lf-at-end_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LayoutTests/fast/xsl/xslt-bad-import-uri_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Completer/completeError_A01_t01: Crash # unsupported element kind: futures:field
-LibTest/async/Completer/completeError_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Completer/completeError_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Completer/completeError_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/async/Completer/complete_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Completer/complete_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Completer/complete_A01_t03: Crash # unsupported element kind: _asyncCounter:field
-LibTest/async/Completer/complete_A01_t04: Crash # unsupported element kind: futures:field
-LibTest/async/Completer/complete_A01_t05: Crash # unsupported element kind: _completer:field
-LibTest/async/Completer/complete_A01_t06: Crash # unsupported element kind: _completer:field
 LibTest/async/DeferredLibrary/DeferredLibrary_A01_t01: Crash # (lazy.loadLibrary()): handleStaticGetterInvoke: foreign: getter(loadLibrary)
-LibTest/async/Future/Future.delayed_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.delayed_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.delayed_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.delayed_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.error_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.error_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.microtask_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.microtask_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.microtask_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.sync_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.sync_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.sync_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.value_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future.value_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/Future_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/asStream_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/asStream_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/asStream_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/asStream_A02_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/catchError_A01_t02: Crash # unsupported element kind: _asyncCounter:field
-LibTest/async/Future/catchError_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/catchError_A03_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/async/Future/catchError_A03_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/catchError_A03_t03: Crash # unsupported element kind: _asyncCounter:field
-LibTest/async/Future/catchError_A03_t04: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/catchError_A03_t05: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/forEach_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/forEach_A02_t01: Crash # unsupported element kind: N:field
-LibTest/async/Future/forEach_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/then_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/then_A01_t02: Crash # unsupported element kind: _asyncCounter:field
-LibTest/async/Future/then_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/then_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/then_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/then_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/then_A03_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/then_A04_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/then_A05_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/then_A05_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/then_A05_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/wait_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/wait_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/wait_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/wait_A01_t05: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/wait_A01_t06: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/wait_A01_t07: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/wait_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/wait_A02_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/whenComplete_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/whenComplete_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/whenComplete_A03_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/async/Future/whenComplete_A04_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Future/whenComplete_A04_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/Stream.eventTransformed_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/Stream.eventTransformed_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/Stream.fromFuture_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/Stream.fromFuture_A02_t02: Crash # unsupported element kind: error:field
-LibTest/async/Stream/Stream.fromIterable_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/Stream.fromIterable_A02_t01: Crash # unsupported element kind: _completer:field
 LibTest/async/Stream/Stream.periodic_A01_t01: Crash # Please triage this failure.
-LibTest/async/Stream/Stream.periodic_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/Stream.periodic_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/any_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/any_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/any_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/asBroadcastStream_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/asBroadcastStream_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/asBroadcastStream_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/asBroadcastStream_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/asBroadcastStream_A03_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/asBroadcastStream_A03_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/asBroadcastStream_A04_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/asBroadcastStream_A04_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/asBroadcastStream_A04_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/contains_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/contains_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/contains_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/distinct_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/distinct_A01_t02: Crash # unsupported element kind: _completer:field
 LibTest/async/Stream/drain_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LibTest/async/Stream/drain_A02_t01: Crash # Please triage this failure.
-LibTest/async/Stream/drain_A02_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/elementAt_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/elementAt_A01_t02: Crash # unsupported element kind: _asyncCounter:field
 LibTest/async/Stream/elementAt_A02_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LibTest/async/Stream/elementAt_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/every_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/every_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/expand_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/firstWhere_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/firstWhere_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/firstWhere_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/firstWhere_A03_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/first_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/first_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/first_A02_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/first_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/fold_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/fold_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/forEach_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/forEach_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/forEach_A02_t02: Crash # unsupported element kind: _completer:field
 LibTest/async/Stream/handleError_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LibTest/async/Stream/handleError_A02_t01: Crash # unsupported element kind: _completer:field
 LibTest/async/Stream/handleError_A03_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LibTest/async/Stream/handleError_A04_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/handleError_A04_t02: Crash # unsupported element kind: _asyncCounter:field
-LibTest/async/Stream/handleError_A04_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/isEmpty_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/join_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/join_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/join_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/join_A02_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/lastWhere_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/lastWhere_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/lastWhere_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/lastWhere_A04_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/last_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/last_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/last_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/length_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/listen_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/listen_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/listen_A03_t01: Crash # unsupported element kind: _completer:field
+LibTest/async/Stream/listen_A03_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 LibTest/async/Stream/listen_A04_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LibTest/async/Stream/listen_A05_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/listen_A05_t02: Crash # unsupported element kind: _asyncCounter:field
-LibTest/async/Stream/listen_A05_t03: Crash # unsupported element kind: _asyncCounter:field
-LibTest/async/Stream/listen_A06_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/map_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/pipe_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/reduce_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/reduce_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/reduce_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/singleWhere_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/singleWhere_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/single_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/single_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/skipWhile_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/skip_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/takeWhile_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/take_A01_t01: Crash # unsupported element kind: _completer:field
 LibTest/async/Stream/take_A01_t02: Crash # Instance of 'TypeOperator': type casts not implemented.
-LibTest/async/Stream/take_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/toList_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/toSet_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/transform_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/transform_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/where_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Stream/where_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController.broadcast_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController.broadcast_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController.broadcast_A04_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController.broadcast_A05_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController.broadcast_A06_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController.broadcast_A07_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController.broadcast_A07_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController.broadcast_A08_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController_A05_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController_A06_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/StreamController_A06_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/addError_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/addError_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/addStream_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/addStream_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/addStream_A02_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/addStream_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/addStream_A03_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/add_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/close_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamController/done_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamIterator/cancel_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamIterator/moveNext_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamIterator/moveNext_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamSink/addError_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamSink/addStream_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamSink/addStream_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamSink/addStream_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamSink/addStream_A01_t05: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamSink/add_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamSink/close_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamSink/done_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamTransformer/StreamTransformer.fromHandlers_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamTransformer/StreamTransformer.fromHandlers_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamTransformer/StreamTransformer.fromHandlers_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamTransformer/StreamTransformer.fromHandlers_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamTransformer/StreamTransformer_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamTransformer/StreamTransformer_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamTransformer/StreamTransformer_A02_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamTransformer/StreamTransformer_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamTransformer/StreamTransformer_A03_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/StreamTransformer/bind_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Timer/Timer.periodic_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Timer/Timer.periodic_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Timer/Timer_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Timer/Timer_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Timer/cancel_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Timer/isActive_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Timer/isActive_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Timer/run_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Timer/run_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Zone/createPeriodicTimer_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Zone/createTimer_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Zone/current_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/async/Zone/handleUncaughtError_A01_t03: Crash # unsupported element kind: stackTraces:field
-LibTest/async/Zone/handleUncaughtError_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/async/Zone/inSameErrorZone_A01_t02: Crash # unsupported element kind: _asyncCounter:field
-LibTest/async/Zone/inSameErrorZone_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/async/Zone/inSameErrorZone_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/async/Zone/inSameErrorZone_A01_t05: Crash # unsupported element kind: _completer:field
 LibTest/async/Zone/registerBinaryCallback_A01_t01: Crash # Instance of 'TypeOperator': type check unimplemented for ZoneBinaryCallback.
 LibTest/async/Zone/registerCallback_A01_t01: Crash # Instance of 'TypeOperator': type check unimplemented for ZoneCallback.
 LibTest/async/Zone/registerUnaryCallback_A01_t01: Crash # Instance of 'TypeOperator': type check unimplemented for ZoneUnaryCallback.
-LibTest/async/Zone/scheduleMicrotask_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/async/Zone/scheduleMicrotask_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/collection/DoubleLinkedQueue/elementAt_A02_t01: Crash # unsupported element kind: queue:field
-LibTest/collection/DoubleLinkedQueue/forEachEntry_A01_t04: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/forEach_A01_t04: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/iterator_A01_t01: Crash # Instance of 'TypeOperator': type check unimplemented for Iterator<int>.
-LibTest/collection/DoubleLinkedQueue/map_A03_t01: Crash # unsupported element kind: visited:field
-LibTest/collection/DoubleLinkedQueue/toList_A01_t03: Crash # unsupported element kind: failures:field
-LibTest/collection/LinkedList/forEach_A02_t01: Crash # unsupported element kind: list:field
-LibTest/collection/LinkedList/lastWhere_A02_t01: Crash # unsupported element kind: noneMatches:field
-LibTest/collection/LinkedList/map_A03_t01: Crash # unsupported element kind: visited:field
-LibTest/collection/LinkedList/toList_A01_t03: Crash # unsupported element kind: failures:field
 LibTest/collection/ListBase/ListBase_class_A01_t02: Crash # Please triage this failure.
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Crash # Please triage this failure.
-LibTest/convert/JsonCodec/decode_A01_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonCodec/decode_A02_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonCodec/decode_A03_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonCodec/encode_A01_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonCodec/encode_A01_t02: Crash # unsupported element kind: table:field
-LibTest/convert/JsonCodec/encode_A02_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonCodec/encode_A02_t03: Crash # unsupported element kind: table:field
-LibTest/convert/JsonCodec/encode_A03_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonDecoder/convert_A01_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonDecoder/convert_A02_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonDecoder/convert_A03_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonDecoder/fuse_A01_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonEncoder/convert_A01_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonEncoder/convert_A02_t01: Crash # unsupported element kind: table:field
-LibTest/convert/JsonEncoder/fuse_A01_t01: Crash # unsupported element kind: table:field
 LibTest/core/FallThroughError/toString_A01_t02: Crash #  Unhandled node
 LibTest/core/Invocation/isAccessor_A01_t01: RuntimeError # Please triage this failure.
 LibTest/core/Invocation/isGetter_A01_t02: RuntimeError # Please triage this failure.
@@ -10770,561 +9907,35 @@
 LibTest/core/Invocation/isSetter_A01_t01: Crash # Please triage this failure.
 LibTest/core/Invocation/memberName_A01_t01: RuntimeError # Please triage this failure.
 LibTest/core/Invocation/positionalArguments_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/List/List.from_A01_t03: Crash # unsupported element kind: failures:field
-LibTest/core/List/List.generate_A01_t03: Crash # unsupported element kind: failures:field
-LibTest/core/List/List_A01_t03: Crash # unsupported element kind: failures:field
 LibTest/core/List/List_class_A01_t02: Crash # Please triage this failure.
 LibTest/core/Map/Map_A01_t01: Crash # Please triage this failure.
-LibTest/core/Object/operator_equality_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
-LibTest/core/Object/toString_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
+LibTest/core/Object/operator_equality_A01_t01 : Crash # Instance of 'TypeOperator': type casts not implemented.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Crash #  Unhandled node
 LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: Crash #  Unhandled node
 LibTest/core/Set/add_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/Stopwatch/elapsedInMs_A01_t01: Crash # unsupported element kind: delay:field
-LibTest/core/Stopwatch/elapsedInUs_A01_t01: Crash # unsupported element kind: delay:field
-LibTest/core/Stopwatch/elapsedTicks_A01_t01: Crash # unsupported element kind: delay:field
-LibTest/core/Stopwatch/elapsedTicks_A01_t02: Crash # unsupported element kind: delay:field
-LibTest/core/Stopwatch/elapsedTicks_A01_t03: Crash # unsupported element kind: delay:field
-LibTest/core/Stopwatch/elapsed_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/core/Stopwatch/elapsed_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/core/Stopwatch/elapsed_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/core/Stopwatch/start_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/core/Stopwatch/start_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/core/Stopwatch/start_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/core/Stopwatch/stop_A01_t01: Crash # unsupported element kind: delay:field
-LibTest/core/String/String_class_A03_t01: RuntimeError # Please triage this failure.
 LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Please triage this failure.
 LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Please triage this failure.
-LibTest/core/Uri/encodeFull_A01_t02: Crash # unsupported element kind: canBeNotEncoded:field
-LibTest/core/Uri/parse_A02_t01: Crash # unsupported element kind: r:field
 LibTest/core/double/INFINITY_A01_t04: Pass # Please triage this failure.
 LibTest/core/double/NEGATIVE_INFINITY_A01_t04: Pass # Please triage this failure.
-LibTest/core/double/operator_GE_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_GE_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_GE_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_GT_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_GT_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_GT_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_LE_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_LE_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_LE_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_LT_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_LT_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_LT_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_addition_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_addition_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_addition_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_addition_A01_t04: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_addition_A01_t07: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_addition_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_division_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_division_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_division_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_division_A01_t04: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_division_A01_t05: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_division_A01_t07: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_division_A01_t08: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_division_A01_t11: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_division_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_multiplication_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_multiplication_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_multiplication_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_multiplication_A01_t04: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_multiplication_A01_t06: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_multiplication_A01_t08: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_multiplication_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_remainder_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_remainder_A01_t04: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_remainder_A01_t05: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_remainder_A01_t06: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_remainder_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_subtraction_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_subtraction_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_subtraction_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_subtraction_A01_t04: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_subtraction_A01_t07: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_subtraction_A01_t08: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_subtraction_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_truncating_division_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_truncating_division_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_truncating_division_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_truncating_division_A01_t05: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_truncating_division_A01_t08: RuntimeError # Please triage this failure.
-LibTest/core/double/operator_truncating_division_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/remainder_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/double/remainder_A01_t04: RuntimeError # Please triage this failure.
-LibTest/core/double/remainder_A01_t05: RuntimeError # Please triage this failure.
-LibTest/core/double/remainder_A01_t06: RuntimeError # Please triage this failure.
-LibTest/core/double/remainder_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/double/toStringAsFixed_A02_t01: RuntimeError # Please triage this failure.
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t05: Crash # unsupported element kind: _completer:field
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t06: Crash # unsupported element kind: _completer:field
-LibTest/html/Document/addEventListener_A01_t01: Crash # unsupported element kind: _completer:field
 LibTest/html/Document/childNodes_A01_t01: Crash # Instance of 'TypeOperator': type check unimplemented for DocumentType.
-LibTest/html/Document/dispatchEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Document/on_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Document/on_A01_t02: Crash # unsupported element kind: _completer:field
 LibTest/html/Document/securityPolicy_A01_t01: Crash # Instance of 'TypeOperator': type check unimplemented for SecurityPolicy.
-LibTest/html/Element/Element.tag_A01_t01: Crash # unsupported element kind: Html5Elements:field
-LibTest/html/Element/abortEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/addEventListener_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/addEventListener_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/addEventListener_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/addEventListener_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/addEventListener_A01_t05: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/addEventListener_A01_t06: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/attributeChanged_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/Element/beforeCopyEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/beforeCutEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/beforePasteEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/blurEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/blur_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/changeEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/clickEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/click_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/contextMenuEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/copyEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/cutEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/doubleClickEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/dragEndEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/dragEnterEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/dragEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/dragLeaveEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/dragOverEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/dragStartEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/dropEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/enteredView_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/Element/errorEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/focusEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/focus_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/fullscreenChangeEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/fullscreenErrorEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/inputEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/invalidEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/isTagSupported_A01_t01: Crash # unsupported element kind: Html5Elements:field
-LibTest/html/Element/keyDownEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/keyPressEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/keyUpEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/leftView_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/Element/loadEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/mouseDownEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/mouseEnterEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/mouseLeaveEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/mouseMoveEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/mouseOutEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/mouseOverEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/mouseUpEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/mouseWheelEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onAbort_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onBeforeCopy_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onBeforeCut_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onBeforePaste_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onBlur_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onChange_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onClick_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onContextMenu_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onCopy_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onCut_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onDoubleClick_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onDragEnd_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onDragEnter_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onDragLeave_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onDragOver_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onDragStart_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onDrag_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onDrop_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onError_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onFocus_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onFullscreenChange_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onFullscreenError_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onInput_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onInvalid_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onKeyDown_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onKeyPress_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onKeyUp_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onLoad_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onMouseDown_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onMouseEnter_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onMouseLeave_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onMouseMove_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onMouseOut_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onMouseOver_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onMouseUp_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onMouseWheel_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onPaste_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onReset_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onScroll_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onSearch_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onSelectStart_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onSelect_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onSubmit_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onTouchCancel_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onTouchEnd_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onTouchEnter_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onTouchLeave_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onTouchMove_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onTouchStart_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/onTransitionEnd_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/on_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/pasteEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/removeEventListener_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/Element/removeEventListener_A01_t02: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/Element/resetEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/scrollEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/searchEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/selectEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/selectStartEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/submitEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/tagName_A01_t01: Crash # unsupported element kind: Html5Elements:field
-LibTest/html/Element/touchCancelEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/touchEndEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/touchEnterEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/touchLeaveEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/touchMoveEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/touchStartEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Element/transitionEndEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Event/Event_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Event/Event_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/html/Event/currentTarget_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/Event/defaultPrevented_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/Event/eventPhase_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/Event/matchingTarget_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/Event/matchingTarget_A01_t02: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/Event/stopImmediatePropagation_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Event/stopImmediatePropagation_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/html/Event/stopPropagation_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Event/target_A01_t01: Crash # unsupported element kind: _asyncCounter:field
 LibTest/html/HttpRequest/abort_A01_t01: Crash #  Unhandled node
-LibTest/html/HttpRequest/addEventListener_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/HttpRequest/dispatchEvent_A01_t01: Crash # unsupported element kind: _completer:field
 LibTest/html/HttpRequest/getAllResponseHeaders_A01_t01: Crash #  Unhandled node
 LibTest/html/HttpRequest/getResponseHeader_A01_t01: Crash #  Unhandled node
-LibTest/html/HttpRequest/getString_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/HttpRequest/onAbort_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/HttpRequest/onError_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/html/HttpRequest/onLoadEnd_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/HttpRequest/onLoadStart_A01_t01: Crash # unsupported element kind: _completer:field
 LibTest/html/HttpRequest/onLoad_A01_t01: Crash #  Unhandled node
-LibTest/html/HttpRequest/onReadyStateChange_A01_t01: Crash # unsupported element kind: _completer:field
 LibTest/html/HttpRequest/overrideMimeType_A01_t01: Crash #  Unhandled node
 LibTest/html/HttpRequest/readyStateChangeEvent_A01_t01: Crash #  Unhandled node
-LibTest/html/HttpRequest/request_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/HttpRequest/responseText_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/HttpRequest/responseText_A01_t02: Crash # unsupported element kind: _completer:field
 LibTest/html/HttpRequest/setRequestHeader_A01_t01: Crash #  Unhandled node
-LibTest/html/HttpRequest/statusText_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/HttpRequest/status_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/HttpRequestUpload/onAbort_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/HttpRequestUpload/onError_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Crash # unsupported element kind: _completer:field
 LibTest/html/HttpRequestUpload/onLoad_A01_t01: Crash #  Unhandled node
-LibTest/html/IFrameElement/addEventListener_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/addEventListener_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/addEventListener_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/addEventListener_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/addEventListener_A01_t05: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/addEventListener_A01_t06: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/attributeChanged_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/IFrameElement/blur_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/click_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/contentWindow_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/dispatchEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/enteredView_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/IFrameElement/focus_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/leftView_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/IFrameElement/onAbort_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onBeforeCopy_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onBeforeCut_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onBeforePaste_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onBlur_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onChange_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onClick_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onContextMenu_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onCopy_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onCut_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onDoubleClick_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onDragEnd_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onDragEnter_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onDragLeave_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onDragOver_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onDragStart_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onDrag_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onDrop_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onError_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onFocus_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onFullscreenChange_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onFullscreenError_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onInput_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onInvalid_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onKeyDown_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onKeyPress_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onKeyUp_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onLoad_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onMouseDown_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onMouseEnter_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onMouseLeave_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onMouseMove_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onMouseOut_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onMouseOver_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onMouseUp_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onMouseWheel_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onPaste_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onReset_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onScroll_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onSearch_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onSelectStart_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onSelect_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onSubmit_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onTouchCancel_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onTouchEnd_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onTouchEnter_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onTouchLeave_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onTouchMove_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onTouchStart_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/onTransitionEnd_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/on_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/removeEventListener_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/IFrameElement/removeEventListener_A01_t02: Crash # unsupported element kind: _asyncCounter:field
-LibTest/html/IFrameElement/resetEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/scrollEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/searchEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/selectEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/IFrameElement/selectStartEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Node/addEventListener_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Node/addEventListener_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/html/Node/addEventListener_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/html/Node/addEventListener_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/html/Node/addEventListener_A01_t05: Crash # unsupported element kind: _completer:field
-LibTest/html/Node/dispatchEvent_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Node/on_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Node/ownerDocument_A01_t01: Crash # unsupported element kind: d:field
-LibTest/html/Node/removeEventListener_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Node/removeEventListener_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/html/Window/addEventListener_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Window/animationFrame_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Window/dispatchEvent_A01_t01: Crash # unsupported element kind: _completer:field
 LibTest/html/Window/moveBy_A01_t01: Crash #  try/finally
 LibTest/html/Window/moveTo_A01_t01: Crash #  try/finally
 LibTest/html/Window/moveTo_A02_t01: Crash #  try/finally
-LibTest/html/Window/postMessage_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Window/postMessage_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/html/Window/requestFileSystem_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/html/Window/requestFileSystem_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/html/Window/requestFileSystem_A02_t01: Crash # unsupported element kind: _completer:field
 LibTest/html/Window/resizeBy_A01_t01: Crash #  try/finally
 LibTest/html/Window/resizeTo_A01_t01: Crash #  try/finally
-LibTest/isolate/Isolate/spawnUri_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawnUri_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawnUri_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawnUri_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawnUri_A01_t05: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawnUri_A02_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawnUri_A02_t03: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawnUri_A02_t04: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawn_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawn_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawn_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawn_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/isolate/Isolate/spawn_A01_t05: Crash # unsupported element kind: _completer:field
-LibTest/isolate/RawReceivePort/RawReceivePort_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/RawReceivePort/RawReceivePort_A01_t02: Crash # unsupported element kind: receivePort:field
-LibTest/isolate/RawReceivePort/close_A01_t01: Crash # unsupported element kind: receivePort:field
-LibTest/isolate/RawReceivePort/handler_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/isolate/RawReceivePort/sendPort_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-LibTest/isolate/ReceivePort/any_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/any_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t03: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/asBroadcastStream_A04_t03: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/close_A01_t01: Crash # unsupported element kind: receivePort:field
-LibTest/isolate/ReceivePort/close_A02_t01: Crash # unsupported element kind: receivePort:field
-LibTest/isolate/ReceivePort/contains_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/distinct_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/distinct_A01_t02: Crash # unsupported element kind: _completer:field
 LibTest/isolate/ReceivePort/drain_A02_t01: Crash # Please triage this failure.
-LibTest/isolate/ReceivePort/drain_A02_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/elementAt_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/elementAt_A03_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/every_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/expand_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/firstWhere_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/firstWhere_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/firstWhere_A03_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/first_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/first_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/first_A02_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/fold_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/fold_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/forEach_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/isEmpty_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/join_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/join_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/lastWhere_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/lastWhere_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/lastWhere_A04_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/last_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/last_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/length_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/listen_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/map_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/pipe_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/reduce_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/reduce_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/reduce_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/sendPort_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/singleWhere_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/singleWhere_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/single_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/single_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/skipWhile_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/skip_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/takeWhile_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/take_A01_t01: Crash # unsupported element kind: _completer:field
 LibTest/isolate/ReceivePort/take_A01_t02: Crash # Instance of 'TypeOperator': type casts not implemented.
-LibTest/isolate/ReceivePort/take_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/toList_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/toSet_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/transform_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/transform_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/where_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/ReceivePort/where_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/SendPort/send_A01_t01: Crash # unsupported element kind: _completer:field
-LibTest/isolate/SendPort/send_A01_t02: Crash # unsupported element kind: _completer:field
-LibTest/isolate/SendPort/send_A01_t03: Crash # unsupported element kind: _completer:field
-LibTest/isolate/SendPort/send_A01_t04: Crash # unsupported element kind: _completer:field
-LibTest/isolate/SendPort/send_A02_t01: Crash # unsupported element kind: _completer:field
-LibTest/math/MutableRectangle/MutableRectangle.fromPoints_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/MutableRectangle/MutableRectangle_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/MutableRectangle/boundingBox_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/MutableRectangle/boundingBox_A01_t02: Crash # unsupported element kind: rand:field
-LibTest/math/MutableRectangle/operator_equality_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/Point/distanceTo_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/Point/operator_addition_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/Point/operator_equality_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/Point/operator_mult_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/Point/operator_subtraction_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/Point/squaredDistanceTo_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/Rectangle/Rectangle.fromPoints_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/Rectangle/Rectangle_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/Rectangle/boundingBox_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/math/Rectangle/boundingBox_A01_t02: Crash # unsupported element kind: rand:field
-LibTest/math/Rectangle/operator_equality_A01_t01: Crash # unsupported element kind: rand:field
-LibTest/typed_data/ByteData/ByteData.view_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/ByteData/setInt16_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/ByteData/setInt32_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/ByteData/setInt8_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/ByteData/setUint16_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/ByteData/setUint32_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/ByteData/setUint8_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/Float32List.fromList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/Float32List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/Float32List.view_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/Float32List_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/setAll_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/setRange_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/setRange_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/sort_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/Float64List.fromList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/Float64List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/Float64List.view_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/Float64List_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/setAll_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/setRange_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/setRange_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/sort_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/Int16List.fromList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/Int16List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/Int16List.view_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/Int16List_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/setAll_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/setRange_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/setRange_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/sort_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/Int32List.fromList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/Int32List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/Int32List.view_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/Int32List_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/setAll_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/setRange_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/setRange_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/sort_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/Int8List.fromList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/Int8List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/Int8List.view_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/Int8List_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/setAll_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/setRange_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/setRange_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/sort_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/Uint16List.fromList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/Uint16List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/Uint16List.view_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/Uint16List_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/setAll_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/setRange_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/setRange_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/sort_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/Uint32List.fromList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/Uint32List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/Uint32List.view_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/Uint32List_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/setAll_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/setRange_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/setRange_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/sort_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/Uint8ClampedList.fromList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/Uint8ClampedList.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/Uint8ClampedList.view_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/Uint8ClampedList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/setAll_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/setRange_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/setRange_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/sort_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/Uint8List.fromList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/Uint8List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/Uint8List.view_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/Uint8List_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/setAll_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/setRange_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/setRange_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/sort_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/toList_A01_t01: RuntimeError # Please triage this failure.
 Utils/tests/Expect/approxEquals_A04_t01: RuntimeError # Please triage this failure.
-Utils/tests/Expect/equals_A01_t04: RuntimeError # Please triage this failure.
-Utils/tests/Expect/listEquals_A01_t01: RuntimeError # Please triage this failure.
-Utils/tests/Expect/listEquals_A02_t01: RuntimeError # Please triage this failure.
 Utils/tests/Expect/stringEquals_A02_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/DOMEvents/approved/EventListener.eventHandler_t01: Crash # unsupported element kind: _asyncCounter:field
-WebPlatformTest/DOMEvents/approved/ProcessingInstruction.DOMCharacterDataModified_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/DOMEvents/approved/domnodeinserted_t01: Crash # unsupported element kind: _asyncCounter:field
-WebPlatformTest/Utils/test/asyncTestFail_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/Utils/test/asyncTestFail_t02: Crash # unsupported element kind: _completer:field
-WebPlatformTest/Utils/test/asyncTestPass_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/Utils/test/asyncTestTimeout_t01: Crash # unsupported element kind: _asyncCounter:field
-WebPlatformTest/custom-elements/concepts/type_A04_t01: Crash # unsupported element kind: EXTENDER_CHARS:field
-WebPlatformTest/custom-elements/concepts/type_A05_t01: Crash # unsupported element kind: COMBINING_CHARS:field
-WebPlatformTest/custom-elements/concepts/type_A06_t01: Crash # unsupported element kind: BASE_CHARS_SINGLE:field
-WebPlatformTest/custom-elements/concepts/type_A07_t01: Crash # unsupported element kind: IDEOGRAPHIC_CHARS_SINGLE:field
-WebPlatformTest/custom-elements/concepts/type_A08_t01: Crash # unsupported element kind: DIGIT_CHARS_RANGES:field
 WebPlatformTest/custom-elements/instantiating/createElementNS_A02_t01: Crash #  Unhandled node
 WebPlatformTest/custom-elements/instantiating/createElementNS_A03_t01: Crash #  Unhandled node
 WebPlatformTest/custom-elements/instantiating/createElementNS_A04_t01: Crash #  Unhandled node
@@ -11333,72 +9944,7 @@
 WebPlatformTest/custom-elements/instantiating/createElement_A04_t01: Crash #  Unhandled node
 WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t01: Crash #  Unhandled node
 WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t02: Crash #  Unhandled node
-WebPlatformTest/custom-elements/instantiating/isAttribute_A02_t01: Crash # unsupported element kind: HTML5_TABLE_ELEMENTS:field
-WebPlatformTest/dom/EventTarget/dispatchEvent_A01_t01: Crash # unsupported element kind: _asyncCounter:field
-WebPlatformTest/dom/EventTarget/dispatchEvent_A02_t01: Crash # unsupported element kind: _asyncCounter:field
-WebPlatformTest/dom/EventTarget/dispatchEvent_A03_t01: Crash # unsupported element kind: _asyncCounter:field
-WebPlatformTest/dom/EventTarget/dispatchEvent_A04_t01: Crash # unsupported element kind: _asyncCounter:field
-WebPlatformTest/dom/nodes/Comment-constructor_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/dom/nodes/DOMImplementation-createDocumentType_t01: Crash # unsupported element kind: tests:field
-WebPlatformTest/dom/nodes/DOMImplementation-createDocument_t01: Crash # unsupported element kind: tests:field
-WebPlatformTest/dom/nodes/DOMImplementation-hasFeature_t01: Crash # unsupported element kind: badTests:field
-WebPlatformTest/dom/nodes/Document-createElementNS_t01: Crash # unsupported element kind: invalidNSQNameCombinations:field
-WebPlatformTest/dom/nodes/Node-isEqualNode_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/dom/nodes/Node-parentNode_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/html-imports/link-import_t02: Crash # unsupported element kind: _completer:field
-WebPlatformTest/html-templates/parsing-html-templates/creating-an-element-for-the-token/template-owner-document_t01: Crash # unsupported element kind: HTML5_VOID_ELEMENTS:field
-WebPlatformTest/html-templates/template-element/template-content_t01: Crash # unsupported element kind: HTML5_VOID_ELEMENTS:field
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-image_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-video_t01: Crash # unsupported element kind: _asyncCounter:field
-WebPlatformTest/html/browsers/browsing-the-web/read-text/load-text-plain_t01: Crash # unsupported element kind: _asyncCounter:field
-WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Crash # unsupported element kind: _completer:field
 WebPlatformTest/html/semantics/forms/the-input-element/datetime_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
 WebPlatformTest/html/semantics/forms/the-input-element/valueMode_t01: Crash #  Unhandled node
-WebPlatformTest/html/semantics/interactive-elements/the-details-element/toggleEvent_t01: Crash # unsupported element kind: asyncCompleted:field
-WebPlatformTest/html/semantics/tabular-data/the-table-element/table-rows_t01: Crash # Instance of 'TypeOperator': type check unimplemented for List<TableRowElement>.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: Crash # unsupported element kind: HTML5_ELEMENT_NAMES:field
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-event-interface/event-path-001_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/event-dispatch/test-002_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/event-dispatch/test-003_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/event-retargeting/test-001_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/event-retargeting/test-003_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/event-retargeting/test-004_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-001_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-002_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-003_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-004_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-005_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-006_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-007_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-008_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-009_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t02: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t05: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t06: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-003_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-001_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-002_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/html-forms/test-001_t01: Crash # unsupported element kind: HTML5_FORM_ASSOCIATED_ELEMENTS:field
-WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/html-forms/test-002_t01: Crash # unsupported element kind: HTML5_FORM_ASSOCIATED_ELEMENTS:field
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: Crash # unsupported element kind: HTML5_ELEMENT_NAMES:field
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-005_t01: Crash # unsupported element kind: HTML5_FORM_ASSOCIATED_ELEMENTS:field
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-007_t01: Crash # unsupported element kind: HTML5_FORM_ASSOCIATED_ELEMENTS:field
-WebPlatformTest/webstorage/event_constructor_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_constructor_t02: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_local_key_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_local_newvalue_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_local_oldvalue_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_local_storagearea_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_local_storageeventinit_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_local_url_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_session_key_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_session_newvalue_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_session_oldvalue_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_session_storagearea_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_session_storageeventinit_t01: Crash # unsupported element kind: _completer:field
-WebPlatformTest/webstorage/event_session_url_t01: Crash # unsupported element kind: _completer:field
+Utils/tests/Expect/equals_A01_t04 : RuntimeError
+LibTest/core/Object/toString_A01_t01 : Crash # Instance of 'TypeOperator': type casts not implemented.
diff --git a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
index fe36410..3fc0068 100644
--- a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
+++ b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
@@ -24,13 +24,11 @@
   // Some things in dart_printer are not yet used
   "lib/src/dart_backend/backend_ast_nodes.dart": const [" is never "],
 
-  // Uncalled error methods in SemanticSendVisitor and subclasses.
+  // Uncalled methods in SemanticSendVisitor and subclasses.
   "lib/src/resolution/semantic_visitor.dart": const [
-      "The method 'error"],
+      "The method 'error", "The method 'visit"],
   "lib/src/resolution/semantic_visitor_mixins.dart": const [
-      "The method 'error"],
-  "lib/src/cps_ir/cps_ir_builder_task.dart": const [
-      "The method 'error"],
+      "The class 'Base", "The method 'error", "The method 'visit"],
 
   // Uncalled type predicate.  Keep while related predicates are used.
   "lib/src/ssa/nodes.dart": const [
diff --git a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart b/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
index 9c5861f..211d526 100644
--- a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
+++ b/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
@@ -13,9 +13,7 @@
     show MessageKind;
 import 'package:compiler/src/dart_types.dart' as dart_types
     show DartType;
-import 'package:compiler/src/elements/elements.dart'
-   show Entity, Element, Elements, Local, TypeVariableElement, ErroneousElement,
-         TypeDeclarationElement, ExecutableElement, PublicName;
+import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/elements/modelx.dart'
     show ErroneousElementX, TypeVariableElementX;
 import 'package:compiler/src/tree/tree.dart' show LiteralDartString;
@@ -48,12 +46,14 @@
 /// classes, and erroneous elements conveniently also skip several assertion
 /// checks in CPS IR nodes that are irrelevant to us.
 class DummyElement extends ErroneousElementX
-    implements TypeVariableElement {
+    implements TypeVariableElement, FieldElement {
   DummyElement(String name)
       : super(dart2js.MessageKind.GENERIC, {}, name, null);
 
   final dart_types.DartType bound = null;
   final TypeDeclarationElement typeDeclaration = null;
+
+  noSuchMethod(inv) => super.noSuchMethod(inv);
 }
 
 /// Used whenever a node constructed by [SExpressionUnstringifier] requires
@@ -137,6 +137,7 @@
   static const String SET_MUTABLE_VARIABLE = "SetMutableVariable";
   static const String TYPE_OPERATOR = "TypeOperator";
   static const String SET_STATIC = "SetStatic";
+  static const String GET_LAZY_STATIC = "GetLazyStatic";
 
   // Primitives
   static const String CONSTANT = "Constant";
@@ -250,6 +251,8 @@
         return parseTypeOperator();
       case SET_STATIC:
         return parseSetStatic();
+      case GET_LAZY_STATIC:
+        return parseGetLazyStatic();
       default:
         assert(false);
     }
@@ -561,25 +564,39 @@
 
     dart_types.DartType type = new DummyNamedType(tokens.read());
 
+    List<ir.Primitive> typeArguments = parsePrimitiveList();
+
     Continuation cont = name2variable[tokens.read()];
     assert(cont != null);
 
     tokens.consumeEnd();
-    return new TypeOperator(recv, type, cont, isTypeTest: operator == 'is');
+    return new TypeOperator(recv, type, typeArguments, cont,
+                            isTypeTest: operator == 'is');
   }
 
   /// (SetStatic field value body)
   SetStatic parseSetStatic() {
     tokens.consumeStart(SET_STATIC);
-    Element fieldElement = new DummyElement(tokens.read());
 
+    Element fieldElement = new DummyElement(tokens.read());
     Primitive value = name2variable[tokens.read()];
     assert(value != null);
-
     Expression body = parseExpression();
 
     tokens.consumeEnd();
-    return new SetStatic(fieldElement, value, null).plug(body);
+    return new SetStatic(fieldElement, value, null)..plug(body);
+  }
+
+  /// (GetLazyStatic field cont)
+  GetLazyStatic parseGetLazyStatic() {
+    tokens.consumeStart(GET_LAZY_STATIC);
+
+    Element fieldElement = new DummyElement(tokens.read());
+    Continuation cont = name2variable[tokens.read()];
+    assert(cont != null);
+
+    tokens.consumeEnd();
+    return new GetLazyStatic(fieldElement, cont, null);
   }
 
   /// (LetPrim (name primitive) body)
@@ -698,8 +715,7 @@
 
   MutableVariable addMutableVariable(String name) {
     assert(!name2variable.containsKey(name));
-    MutableVariable variable =
-        new MutableVariable(new DummyElement(""), new DummyElement(name));
+    MutableVariable variable = new MutableVariable(new DummyElement(name));
     name2variable[name] = variable;
     return variable;
   }
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/concrete_type_inference_test.dart
index 07d69fa..fb94801 100644
--- a/tests/compiler/dart2js/concrete_type_inference_test.dart
+++ b/tests/compiler/dart2js/concrete_type_inference_test.dart
@@ -24,7 +24,7 @@
       'print',
       (compiler, printElement) {
         var parameter =
-          printElement.computeSignature(compiler).requiredParameters.head;
+          printElement.computeSignature(compiler).requiredParameters.first;
         var type = compiler.typesTask.getGuaranteedTypeOfElement(parameter);
         checkType(compiler, type);
       }));
@@ -34,7 +34,7 @@
       'print',
       (compiler, printElement) {
         var parameter =
-          printElement.computeSignature(compiler).requiredParameters.head;
+          printElement.computeSignature(compiler).requiredParameters.first;
         var type = compiler.typesTask.getGuaranteedTypeOfElement(parameter);
         checkType(compiler, type);
       }));
@@ -44,7 +44,7 @@
       'print',
       (compiler, printElement) {
         var parameter =
-          printElement.computeSignature(compiler).requiredParameters.head;
+          printElement.computeSignature(compiler).requiredParameters.first;
         var type = compiler.typesTask.getGuaranteedTypeOfElement(parameter);
         checkType(compiler, type);
       }));
@@ -85,11 +85,11 @@
       'fisk',
       (compiler, fiskElement) {
         var firstParameter =
-          fiskElement.computeSignature(compiler).requiredParameters.head;
+          fiskElement.computeSignature(compiler).requiredParameters[0];
         var secondParameter =
-          fiskElement.computeSignature(compiler).optionalParameters.head;
+          fiskElement.computeSignature(compiler).optionalParameters[0];
         var thirdParameter =
-          fiskElement.computeSignature(compiler).optionalParameters.tail.head;
+          fiskElement.computeSignature(compiler).optionalParameters[1];
         var typesTask = compiler.typesTask;
         var inferrer = typesTask.typesInferrer;
         Expect.identical(
diff --git a/tests/compiler/dart2js/incremental/compile_all.dart b/tests/compiler/dart2js/incremental/compile_all.dart
index 0c35641..c2c7a9e 100644
--- a/tests/compiler/dart2js/incremental/compile_all.dart
+++ b/tests/compiler/dart2js/incremental/compile_all.dart
@@ -9,7 +9,7 @@
 
 import 'dart:io';
 
-import 'dart:profiler' show
+import 'dart:developer' show
     UserTag;
 
 import 'package:dart2js_incremental/dart2js_incremental.dart' show
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
index 2c62b87..b9183bc 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
@@ -106,7 +106,7 @@
   print(new Set.from([1, 2, 3]));
 }""", r"""
 function() {
-  P.print(P.LinkedHashSet_LinkedHashSet(null));
+  P.print(P.LinkedHashSet_LinkedHashSet(null, null, null, null));
   P.print(P.LinkedHashSet_LinkedHashSet$from([1, 2, 3], null));
   return null;
 }"""),
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_runtime_types_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_runtime_types_test.dart
index 907484f..4353b69 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_runtime_types_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_runtime_types_test.dart
@@ -40,7 +40,7 @@
 }""",
 """
 function() {
-  return P.print($createType($typeToString($getSubstitutedTypeArgument(this, "\$asC", 1))));
+  return P.print($createType($typeToString($getSubstitutedTypeArgument(this, "C", 1))));
 }"""),
   const TestEntry.forMethod('function(C#foo)', r"""
 class C<T> {
diff --git a/tests/compiler/dart2js/js_spec_string_test.dart b/tests/compiler/dart2js/js_spec_string_test.dart
index 876c87c..5344177 100644
--- a/tests/compiler/dart2js/js_spec_string_test.dart
+++ b/tests/compiler/dart2js/js_spec_string_test.dart
@@ -20,7 +20,7 @@
     errorMessage = message;
     throw "error";
   }
-  reportError(spannable, kind, arguments) {
+  reportError(spannable, kind, [arguments]) {
     errorMessage = '$arguments';  // E.g.  "{text: Duplicate tag 'new'.}"
     throw "error";
   }
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/parser_helper.dart
index 1e58768..acd2c030 100644
--- a/tests/compiler/dart2js/parser_helper.dart
+++ b/tests/compiler/dart2js/parser_helper.dart
@@ -64,7 +64,9 @@
   withCurrentElement(Element element, f()) => f();
 }
 
-Token scan(String text) => new StringScanner.fromString(text).tokenize();
+Token scan(String text) =>
+    new StringScanner.fromString(text, enableNullAwareOperators: true)
+    .tokenize();
 
 Node parseBodyCode(String text, Function parseMethod,
                    {DiagnosticListener diagnosticHandler}) {
diff --git a/tests/compiler/dart2js/parser_test.dart b/tests/compiler/dart2js/parser_test.dart
index 6606f88..1f4cae9 100644
--- a/tests/compiler/dart2js/parser_test.dart
+++ b/tests/compiler/dart2js/parser_test.dart
@@ -144,6 +144,32 @@
   conditional = node.expression;
   Expect.isNotNull(conditional.thenExpression.asSendSet());
   Expect.isNotNull(conditional.elseExpression.asSendSet());
+
+  node = parseStatement("a ?? b ? c : d;");
+  // Should parse as: (a ?? b) ? c : d;
+  conditional = node.expression;
+  Expect.isNotNull(conditional.condition.asSend());
+  Expect.isTrue(conditional.condition.asSend().isIfNull);
+  Expect.isNotNull(conditional.thenExpression.asSend());
+  Expect.isNotNull(conditional.elseExpression.asSend());
+}
+
+void testNullOperators() {
+  Expression node = parseStatement("a ?? b;").expression;
+  Expect.isNotNull(node.asSend());
+  Expect.isTrue(node.asSend().isIfNull);
+
+  node = parseStatement("a ??= b;").expression;
+  Expect.isNotNull(node.asSendSet());
+  Expect.isTrue(node.asSendSet().isIfNullAssignment);
+
+  node = parseStatement("a?.b;").expression;
+  Expect.isNotNull(node.asSend());
+  Expect.isTrue(node.asSend().isConditional);
+
+  node = parseStatement("a?.m();").expression;
+  Expect.isNotNull(node.asSend());
+  Expect.isTrue(node.asSend().isConditional);
 }
 
 void testAssignment() {
@@ -338,6 +364,7 @@
   testDoStatement();
   testWhileStatement();
   testConditionalExpression();
+  testNullOperators();
   testAssignment();
   testIndex();
   testPostfix();
diff --git a/tests/compiler/dart2js/semantic_visitor_test.dart b/tests/compiler/dart2js/semantic_visitor_test.dart
index 3d93724..663b041 100644
--- a/tests/compiler/dart2js/semantic_visitor_test.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test.dart
@@ -5,6 +5,7 @@
 library dart2js.semantics_visitor_test;

 

 import 'dart:async';

+import 'dart:mirrors';

 import 'package:async_helper/async_helper.dart';

 import 'package:expect/expect.dart';

 import 'package:compiler/src/constants/expressions.dart';

@@ -176,6 +177,11 @@
                     element: 'parameter(m#o)',

                     arguments: '(null,42)',

                     selector: 'CallStructure(arity=2)')),

+    // TODO(johnniwinther): Expect [VISIT_FINAL_PARAMETER_SET] instead.

+    const Test('m(final o) { o = 42; }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs:'42')),

   ],

   'Local variables': const [

     // Local variables

@@ -191,6 +197,16 @@
                     element: 'variable(m#o)',

                     arguments: '(null,42)',

                     selector: 'CallStructure(arity=2)')),

+    // TODO(johnniwinther): Expect [VISIT_FINAL_LOCAL_VARIABLE_SET] instead.

+    const Test('m() { final o = 0; o = 42; }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs:'42')),

+    // TODO(johnniwinther): Expect [VISIT_FINAL_LOCAL_VARIABLE_SET] instead.

+    const Test('m() { const o = 0; o = 42; }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs:'42')),

   ],

   'Local functions': const [

     // Local functions

@@ -202,6 +218,11 @@
                     element: 'function(m#o)',

                     arguments: '(null,42)',

                     selector: 'CallStructure(arity=2)')),

+    // TODO(johnniwinther): Expect [VISIT_LOCAL_FUNCTION_SET] instead.

+    const Test('m() { o(a, b) {}; o = 42; }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

   ],

   'Static fields': const [

     // Static fields

@@ -315,6 +336,83 @@
         const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,

                     element: 'field(C#o)',

                     arguments: '(null,42)')),

+    // TODO(johnniwinther): Expect [VISIT_FINAL_STATIC_FIELD_SET] instead.

+    const Test(

+        '''

+        class C { static final o = 0; }

+        m() { C.o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static final o = 0;

+          m() { o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static final o = 0;

+          m() { C.o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        class C {

+          static final o = 0;

+        }

+        ''',

+        'm() { p.C.o = 42; }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test(

+        '''

+        class C { static const o = 0; }

+        m() { C.o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static const o = 0;

+          m() { o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static const o = 0;

+          m() { C.o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        class C {

+          static const o = 0;

+        }

+        ''',

+        'm() { p.C.o = 42; }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

   ],

   'Static properties': const [

     // Static properties

@@ -354,6 +452,82 @@
         'm() => p.C.o;',

         const Visit(VisitKind.VISIT_STATIC_GETTER_GET,

                     element: 'getter(C#o)')),

+    // TODO(johnniwinther): Expected [VISIT_STATIC_GETTER_SET] instead.

+    const Test(

+        '''

+        class C { static get o => 42; }

+        m() { C.o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static static get o => 42;

+          m() { o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static static get o => 42;

+          m() { C.o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        class C {

+          static static get o => 42;

+        }

+        ''',

+        'm() { p.C.o = 42; }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    // TODO(johnniwinther): Expected [VISIT_STATIC_SETTER_GET] instead.

+    const Test(

+        '''

+        class C {

+          static set o(_) {}

+        }

+        m() => C.o;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_GET,

+                    name: 'o')),

+    const Test.clazz(

+        '''

+        class C {

+          static set o(_) {}

+          m() => o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_GET,

+                    name: 'o')),

+    const Test.clazz(

+        '''

+        class C {

+          static set o(_) {}

+          m() => C.o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_GET,

+                    name: 'o')),

+    const Test.prefix(

+        '''

+        class C {

+          static set o(_) {}

+        }

+        ''',

+        'm() => p.C.o;',

+        const Visit(VisitKind.VISIT_UNRESOLVED_GET,

+                    name: 'o')),

     const Test(

         '''

         class C { static set o(_) {} }

@@ -430,6 +604,45 @@
         const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,

                     element: 'getter(C#o)',

                     arguments: '(null,42)')),

+    // TODO(johnniwinther): Expect [VISIT_STATIC_SETTER_INVOKE] instead.

+    const Test(

+        '''

+        class C { static set o(_) {} }

+        m() => C.o(null, 42);

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

+                    name: 'o',

+                    arguments: '(null,42)')),

+    const Test.clazz(

+        '''

+        class C {

+          static set o(_) {}

+          m() { o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

+                    name: 'o',

+                    arguments: '(null,42)')),

+    const Test.clazz(

+        '''

+        class C {

+          static set o(_) {}

+          m() { C.o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

+                    name: 'o',

+                    arguments: '(null,42)')),

+    const Test.prefix(

+        '''

+        class C {

+          static set o(_) {}

+        }

+        ''',

+        'm() { p.C.o(null, 42); }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

+                    name: 'o',

+                    arguments: '(null,42)')),

   ],

   'Static functions': const [

     // Static functions

@@ -467,6 +680,45 @@
         ''',

         const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,

                     element: 'function(C#o)')),

+    // TODO(johnniwinther): Expect [VISIT_STATIC_FUNCTION_SET] instead.

+    const Test(

+        '''

+        class C { static o(a, b) {} }

+        m() { C.o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static o(a, b) {}

+          m() { o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static o(a, b) {}

+          m() { C.o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        class C { static o(a, b) {} }

+        ''',

+        '''

+        m() { p.C.o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

     const Test(

         '''

         class C { static o(a, b) {} }

@@ -546,6 +798,39 @@
         const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,

                     element: 'field(o)',

                     rhs: '42')),

+    // TODO(johnniwinther): Expect [VISIT_FINAL_TOP_LEVEL_FIELD_SET] instead.

+    const Test(

+        '''

+        final o = 0;

+        m() { o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        final o = 0;

+        ''',

+        'm() { p.o = 42; }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test(

+        '''

+        const o = 0;

+        m() { o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        const o = 0;

+        ''',

+        'm() { p.o = 42; }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

     const Test(

         '''

         var o;

@@ -587,6 +872,40 @@
         ''',

         const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,

                     element: 'getter(o)')),

+    // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_SETTER_GET] instead.

+    const Test(

+        '''

+        set o(_) {}

+        m() => o;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_GET,

+                    name: 'o')),

+    const Test.prefix(

+        '''

+        set o(_) {}

+        ''',

+        '''

+        m() => p.o;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_GET,

+                    name: 'o')),

+    // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_GETTER_SET] instead.

+    const Test(

+        '''

+        get o => null;

+        m() { o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        get o => null;

+        ''',

+        'm() { p.o = 42; }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

     const Test(

         '''

         set o(_) {}

@@ -619,6 +938,23 @@
         const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,

                     element: 'getter(o)',

                     arguments: '(null,42)')),

+    // TODO(johnniwinther): Expected [VISIT_TOP_LEVEL_SETTER_INVOKE] instead.

+    const Test(

+        '''

+        set o(_) {}

+        m() => o(null, 42);

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

+                    name: 'o',

+                    arguments: '(null,42)')),

+    const Test.prefix(

+        '''

+        set o(_) {}

+        ''',

+        'm() { p.o(null, 42); }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

+                    name: 'o',

+                    arguments: '(null,42)')),

   ],

   'Top level functions': const [

     // Top level functions

@@ -660,6 +996,23 @@
         const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

                     name: 'o',

                     arguments: '(null,42)')),

+    // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_FUNCTION_SET] instead.

+    const Test(

+        '''

+        o(a, b) {}

+        m() { o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        o(a, b) {}

+        ''',

+        'm() { p.o = 42; }',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

   ],

   'Dynamic properties': const [

     // Dynamic properties

@@ -833,6 +1186,19 @@
         const Visit(VisitKind.VISIT_SUPER_FIELD_SET,

                     element: 'field(B#o)',

                     rhs: '42')),

+    // TODO(johnniwinther): Expect [VISIT_FINAL_SUPER_FIELD_SET] instead.

+    const Test.clazz(

+        '''

+        class B {

+          final o = 0;

+        }

+        class C extends B {

+          m() { super.o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

     const Test.clazz(

         '''

         class B {

@@ -868,6 +1234,30 @@
         ''',

         const Visit(VisitKind.VISIT_SUPER_GETTER_GET,

                     element: 'getter(B#o)')),

+    // TODO(johnniwinther): Expect [VISIT_SUPER_SETTER_GET] instead.

+    const Test.clazz(

+        '''

+        class B {

+          set o(_) {}

+        }

+        class C extends B {

+          m() => super.o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GET)),

+    // TODO(johnniwinther): Expect [VISIT_SUPER_GETTER_SET] instead.

+    const Test.clazz(

+        '''

+        class B {

+          get o => 0;

+        }

+        class C extends B {

+          m() { super.o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                    name: 'o',

+                    rhs: '42')),

     const Test.clazz(

         '''

         class B {

@@ -892,6 +1282,18 @@
         const Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,

                     element: 'getter(B#o)',

                     arguments: '(null,42)')),

+    // TODO(johnniwinther): Expect [VISIT_SUPER_SETTER_INVOKE] instead.

+    const Test.clazz(

+        '''

+        class B {

+          set o(_) {}

+        }

+        class C extends B {

+          m() { super.o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INVOKE,

+                    arguments: '(null,42)')),

   ],

   'Super methods': const [

     // Super methods

@@ -965,6 +1367,38 @@
         const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,

                     constant: 'C',

                     arguments: '(null,42)')),

+    const Test(

+        '''

+        class C {}

+        m() => C += 42;

+        ''',

+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,

+                    constant: 'C',

+                    operator: '+=',

+                    rhs: '42')),

+    const Test(

+        '''

+        class C {}

+        m() => ++C;

+        ''',

+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,

+                    constant: 'C',

+                    operator: '++')),

+    const Test(

+        '''

+        class C {}

+        m() => C--;

+        ''',

+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_POSTFIX,

+                    constant: 'C',

+                    operator: '--')),

+    const Test(

+        '''

+        class C {}

+        m() => C;

+        ''',

+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,

+                    constant: 'C')),

   ],

   'Typedef type literals': const [

     // Typedef type literals

@@ -983,6 +1417,31 @@
         const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,

                     constant: 'F',

                     arguments: '(null,42)')),

+    const Test(

+        '''

+        typedef F();

+        m() => F += 42;

+        ''',

+        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,

+                    constant: 'F',

+                    operator: '+=',

+                    rhs: '42')),

+    const Test(

+        '''

+        typedef F();

+        m() => ++F;

+        ''',

+        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,

+                    constant: 'F',

+                    operator: '++')),

+    const Test(

+        '''

+        typedef F();

+        m() => F--;

+        ''',

+        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,

+                    constant: 'F',

+                    operator: '--')),

   ],

   'Type variable type literals': const [

     // Type variable type literals

@@ -1003,6 +1462,34 @@
         const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,

                     element: 'type_variable(C#T)',

                     arguments: '(null,42)')),

+    const Test.clazz(

+        '''

+        class C<T> {

+          m() => T += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

+                    element: 'type_variable(C#T)',

+                    operator: '+=',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C<T> {

+          m() => ++T;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,

+                    element: 'type_variable(C#T)',

+                    operator: '++')),

+    const Test.clazz(

+        '''

+        class C<T> {

+          m() => T--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,

+                    element: 'type_variable(C#T)',

+                    operator: '--')),

 

   ],

   'Dynamic type literals': const [

@@ -1013,15 +1500,38 @@
         ''',

         const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_GET,

                     constant: 'dynamic')),

-    // TODO(johnniwinther): Enable this when we pass the right constant.

-    // Currently we generated the constant for `Type` instead of `dynamic`.

-    /*const Test(

+    // TODO(johnniwinther): Update these to expect the constant to be `dynamic`

+    // instead of `Type`. Currently the compile time constant evaluator cannot

+    // detect `dynamic` as a constant subexpression.

+    const Test(

         '''

         m() { dynamic(null, 42); }

         ''',

         const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,

-                    constant: 'dynamic',

-                    arguments: '(null,42)')),*/

+                    constant: 'Type',

+                    arguments: '(null,42)')),

+    const Test(

+        '''

+        m() => dynamic += 42;

+        ''',

+        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,

+                    constant: 'Type',

+                    operator: '+=',

+                    rhs: '42')),

+    const Test(

+        '''

+        m() => ++dynamic;

+        ''',

+        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,

+                    constant: 'Type',

+                    operator: '++')),

+    const Test(

+        '''

+        m() => dynamic--;

+        ''',

+        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,

+                    constant: 'Type',

+                    operator: '--')),

   ],

   'Assert': const [

     // Assert

@@ -1257,6 +1767,7 @@
         }

         ''',

         const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,

+                    setter: 'function(B#[]=)',

                     index: '42',

                     operator: '++')),

     const Test.clazz(

@@ -1267,7 +1778,7 @@
           m() => ++super[42];

         }

         ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,

                     index: '42',

                     operator: '++')),

     const Test.clazz(

@@ -1308,6 +1819,7 @@
         }

         ''',

         const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,

+                    setter: 'function(B#[]=)',

                     index: '42',

                     operator: '--')),

     const Test.clazz(

@@ -1318,7 +1830,7 @@
           m() => super[42]--;

         }

         ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,

                     index: '42',

                     operator: '--')),

     const Test.clazz(

@@ -1364,8 +1876,7 @@
         ''',

         const Visit(VisitKind.VISIT_NOT_EQUALS,

                     left: '2', right: '3')),

-    // TODO(johnniwinther): Enable this. Resolution does not store the element.

-    /*const Test.clazz(

+    const Test.clazz(

         '''

         class B {

           operator ==(_) => null;

@@ -1376,7 +1887,7 @@
         ''',

         const Visit(VisitKind.VISIT_SUPER_NOT_EQUALS,

                     element: 'function(B#==)',

-                    right: '42')),*/

+                    right: '42')),

   ],

   'Unary expression': const [

     // Unary expression

@@ -1474,37 +1985,6 @@
           const Visit(VisitKind.VISIT_PARAMETER_GET,

               element: 'parameter(m#a)')

         ]),

-    // TODO(johnniwinther): Enable this when type literals are recognized in

-    // SendSet.

-    /*const Test(

-        '''

-        class C {}

-        m(a) => C += 42;

-        ''',

-        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,

-            constant: 'C', operator: '+=', rhs: '42')),

-    const Test(

-        '''

-        typedef F();

-        m(a) => F += 42;

-        ''',

-        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,

-            constant: 'F', operator: '+=', rhs: '42')),

-    const Test.clazz(

-        '''

-        class C<T> {

-          m(a) => T += 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

-            element: 'type_variable(C#T)', operator: '+=', rhs: '42')),

-    const Test(

-        '''

-        m(a) => dynamic += 42;

-        ''',

-        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,

-            constant: 'dynamic',

-            operator: '+=', rhs: '42')),*/

     const Test(

         '''

         m(a) => a += 42;

@@ -1513,6 +1993,12 @@
             element: 'parameter(m#a)', operator: '+=', rhs: '42')),

     const Test(

         '''

+        m(final a) => a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_FINAL_PARAMETER_COMPOUND,

+            element: 'parameter(m#a)', operator: '+=', rhs: '42')),

+    const Test(

+        '''

         m() {

           var a;

           a += 42;

@@ -1522,6 +2008,24 @@
             element: 'variable(m#a)', operator: '+=', rhs: '42')),

     const Test(

         '''

+        m() {

+          final a;

+          a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,

+            element: 'variable(m#a)', operator: '+=', rhs: '42')),

+    const Test(

+        '''

+        m() {

+          a() {}

+          a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_COMPOUND,

+            element: 'function(m#a)', operator: '+=', rhs: '42')),

+    const Test(

+        '''

         var a;

         m() => a += 42;

         ''',

@@ -1704,6 +2208,17 @@
     const Test.clazz(

         '''

         class B {

+          final a = 0;

+        }

+        class C extends B {

+          m() => super.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_COMPOUND,

+            element: 'field(B#a)', operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class B {

           get a => 0;

           set a (_) {}

         }

@@ -1778,6 +2293,129 @@
         const Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,

             getter: 'field(B#a)', setter: 'field(A#a)',

             operator: '+=', rhs: '42')),*/

+    const Test.clazz(

+        '''

+        class B {

+          a() {}

+        }

+        class C extends B {

+          m() => super.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_METHOD_COMPOUND,

+            element: 'function(B#a)',

+            operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class B {

+        }

+        class C extends B {

+          m() => super.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND,

+            operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class B {

+          set a(_) {}

+        }

+        class C extends B {

+          m() => super.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,

+            setter: 'setter(B#a)', operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class B {

+          get a => 42;

+        }

+        class C extends B {

+          m() => super.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,

+            getter: 'getter(B#a)', operator: '+=', rhs: '42')),

+

+    const Test.clazz(

+        '''

+        class C {

+          static set a(var value) { }

+          m() => a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,

+            setter: 'setter(C#a)', operator: '+=', rhs: '42')),

+

+    const Test.clazz(

+        '''

+        class C {

+          static get a => 42;

+          m() => C.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,

+            getter: 'getter(C#a)', operator: '+=', rhs: '42')),

+

+    const Test.clazz(

+        '''

+        class C {

+          static final a = 42;

+          m() => C.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_COMPOUND,

+            element: 'field(C#a)', operator: '+=', rhs: '42')),

+

+    const Test(

+        '''

+        class C {

+          static a(var value) { }

+        }

+        m() => C.a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_METHOD_COMPOUND,

+            element: 'function(C#a)', operator: '+=', rhs: '42')),

+

+    const Test(

+        '''

+        set a(var value) { }

+        m() => a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,

+            setter: 'setter(a)', operator: '+=', rhs: '42')),

+

+    const Test(

+        '''

+        get a => 42;

+        m() => a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,

+            getter: 'getter(a)', operator: '+=', rhs: '42')),

+

+    const Test(

+        '''

+        a(var value) { }

+        m() => a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_COMPOUND,

+            element: 'function(a)', operator: '+=', rhs: '42')),

+

+    const Test(

+        '''

+        final a = 42;

+        m() => a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,

+            element: 'field(a)', operator: '+=', rhs: '42')),

+

+    const Test(

+        '''

+        m() => unresolved += 42;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_COMPOUND,

+            operator: '+=', rhs: '42')),

   ],

   'Compound index assignment': const [

     // Compound index assignment

@@ -1810,6 +2448,7 @@
         }

         ''',

         const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,

+            setter: 'function(B#[]=)',

             index: '1', operator: '+=', rhs: '42')),

     const Test.clazz(

         '''

@@ -1819,7 +2458,7 @@
           m() => super[1] += 42;

         }

         ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,

             index: '1', operator: '+=', rhs: '42')),

     const Test.clazz(

         '''

@@ -1856,6 +2495,12 @@
             element: 'parameter(m#a)', operator: '++')),

     const Test(

         '''

+        m(final a) => ++a;

+        ''',

+        const Visit(VisitKind.VISIT_FINAL_PARAMETER_PREFIX,

+            element: 'parameter(m#a)', operator: '++')),

+    const Test(

+        '''

         m() {

           var a;

           --a;

@@ -1865,6 +2510,24 @@
             element: 'variable(m#a)', operator: '--')),

     const Test(

         '''

+        m() {

+          final a = 42;

+          --a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_PREFIX,

+            element: 'variable(m#a)', operator: '--')),

+    const Test(

+        '''

+        m() {

+          a() {}

+          --a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_PREFIX,

+            element: 'function(m#a)', operator: '--')),

+    const Test(

+        '''

         var a;

         m() => ++a;

         ''',

@@ -1999,6 +2662,17 @@
     const Test.clazz(

         '''

         class B {

+          final a = 0;

+        }

+        class C extends B {

+          m() => --super.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_PREFIX,

+            element: 'field(B#a)', operator: '--')),

+    const Test.clazz(

+        '''

+        class B {

           get a => 0;

           set a (_) {}

         }

@@ -2056,6 +2730,129 @@
         const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_PREFIX,

             getter: 'field(A#a)', setter: 'setter(B#a)',

             operator: '++')),

+    const Test.clazz(

+        '''

+        class B {

+          a() {}

+        }

+        class C extends B {

+          m() => ++super.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_METHOD_PREFIX,

+            element: 'function(B#a)',

+            operator: '++')),

+    const Test.clazz(

+        '''

+        class B {

+        }

+        class C extends B {

+          m() => ++super.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_PREFIX,

+            operator: '++')),

+    const Test.clazz(

+        '''

+        class B {

+          set a(_) {}

+        }

+        class C extends B {

+          m() => ++super.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,

+            setter: 'setter(B#a)', operator: '++')),

+    const Test.clazz(

+        '''

+        class B {

+          get a => 42;

+        }

+        class C extends B {

+          m() => ++super.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,

+            getter: 'getter(B#a)', operator: '++')),

+

+    const Test.clazz(

+        '''

+        class C {

+          static set a(var value) { }

+          m() => ++a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,

+            setter: 'setter(C#a)', operator: '++')),

+

+    const Test.clazz(

+        '''

+        class C {

+          static get a => 42;

+          m() => ++C.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,

+            getter: 'getter(C#a)', operator: '++')),

+

+    const Test.clazz(

+        '''

+        class C {

+          static final a = 42;

+          m() => ++C.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_PREFIX,

+            element: 'field(C#a)', operator: '++')),

+

+    const Test(

+        '''

+        class C {

+          static a(var value) { }

+        }

+        m() => ++C.a;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_METHOD_PREFIX,

+            element: 'function(C#a)', operator: '++')),

+

+    const Test(

+        '''

+        set a(var value) { }

+        m() => ++a;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,

+            setter: 'setter(a)', operator: '++')),

+

+    const Test(

+        '''

+        get a => 42;

+        m() => ++a;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,

+            getter: 'getter(a)', operator: '++')),

+

+    const Test(

+        '''

+        a(var value) { }

+        m() => ++a;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_PREFIX,

+            element: 'function(a)', operator: '++')),

+

+    const Test(

+        '''

+        final a = 42;

+        m() => ++a;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,

+            element: 'field(a)', operator: '++')),

+

+    const Test(

+        '''

+        m() => ++unresolved;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_PREFIX,

+            operator: '++')),

   ],

   'Postfix expression': const [

     // Postfix expression

@@ -2079,6 +2876,12 @@
             element: 'parameter(m#a)', operator: '++')),

     const Test(

         '''

+        m(final a) => a++;

+        ''',

+        const Visit(VisitKind.VISIT_FINAL_PARAMETER_POSTFIX,

+            element: 'parameter(m#a)', operator: '++')),

+    const Test(

+        '''

         m() {

           var a;

           a--;

@@ -2088,6 +2891,24 @@
             element: 'variable(m#a)', operator: '--')),

     const Test(

         '''

+        m() {

+          final a = 42;

+          a--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,

+            element: 'variable(m#a)', operator: '--')),

+    const Test(

+        '''

+        m() {

+          a() {}

+          a--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_POSTFIX,

+            element: 'function(m#a)', operator: '--')),

+    const Test(

+        '''

         var a;

         m() => a++;

         ''',

@@ -2222,6 +3043,17 @@
     const Test.clazz(

         '''

         class B {

+          final a = 0;

+        }

+        class C extends B {

+          m() => super.a--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_POSTFIX,

+            element: 'field(B#a)', operator: '--')),

+    const Test.clazz(

+        '''

+        class B {

           get a => 0;

           set a (_) {}

         }

@@ -2279,13 +3111,128 @@
         const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_POSTFIX,

             getter: 'field(A#a)', setter: 'setter(B#a)',

             operator: '++')),

+    const Test.clazz(

+        '''

+        class B {

+          a() {}

+        }

+        class C extends B {

+          m() => super.a++;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_METHOD_POSTFIX,

+            element: 'function(B#a)',

+            operator: '++')),

+    const Test.clazz(

+        '''

+        class B {

+        }

+        class C extends B {

+          m() => super.a++;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_POSTFIX,

+            operator: '++')),

+    const Test.clazz(

+        '''

+        class B {

+          set a(_) {}

+        }

+        class C extends B {

+          m() => super.a++;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,

+            setter: 'setter(B#a)', operator: '++')),

+    const Test.clazz(

+        '''

+        class B {

+          get a => 42;

+        }

+        class C extends B {

+          m() => super.a++;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,

+            getter: 'getter(B#a)', operator: '++')),

+

+    const Test.clazz(

+        '''

+        class C {

+          static set a(var value) { }

+          m() => a++;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,

+            setter: 'setter(C#a)', operator: '++')),

+

+    const Test.clazz(

+        '''

+        class C {

+          static get a => 42;

+          m() => C.a++;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,

+            getter: 'getter(C#a)', operator: '++')),

+

+    const Test.clazz(

+        '''

+        class C {

+          static final a = 42;

+          m() => C.a++;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_POSTFIX,

+            element: 'field(C#a)', operator: '++')),

 

     const Test(

         '''

-        set topLevel(var value) { }

-        m() => topLevel++;

+        class C {

+          static a(var value) { }

+        }

+        m() => C.a++;

         ''',

-        const Visit(VisitKind.ERROR_UNRESOLVED_POSTFIX,

+        const Visit(VisitKind.VISIT_STATIC_METHOD_POSTFIX,

+            element: 'function(C#a)', operator: '++')),

+

+    const Test(

+        '''

+        set a(var value) { }

+        m() => a++;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,

+            setter: 'setter(a)', operator: '++')),

+

+    const Test(

+        '''

+        get a => 42;

+        m() => a++;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,

+            getter: 'getter(a)', operator: '++')),

+

+    const Test(

+        '''

+        a(var value) { }

+        m() => a++;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_POSTFIX,

+            element: 'function(a)', operator: '++')),

+

+    const Test(

+        '''

+        final a = 42;

+        m() => a++;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,

+            element: 'field(a)', operator: '++')),

+

+    const Test(

+        '''

+        m() => unresolved++;

+        ''',

+        const Visit(VisitKind.VISIT_UNRESOLVED_POSTFIX,

             operator: '++')),

   ],

   'Constructor invocations': const [

@@ -2919,6 +3866,33 @@
     const Test.clazz(

         '''

         class C {

+          var field1;

+          var field2;

+          C(a, b) : this.field1 = a, this.field2 = b;

+        }

+        ''',

+        const [

+          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,

+              element: 'generative_constructor(C#)',

+              parameters: '(a,b)',

+              body: ';'),

+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

+              element: 'parameter(#a)',

+              index: 0),

+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

+              element: 'parameter(#b)',

+              index: 1),

+          const Visit(VisitKind.VISIT_FIELD_INITIALIZER,

+              element: 'field(C#field1)',

+              rhs: 'a'),

+          const Visit(VisitKind.VISIT_FIELD_INITIALIZER,

+              element: 'field(C#field2)',

+              rhs: 'b'),

+        ],

+        method: ''),

+    const Test.clazz(

+        '''

+        class C {

           C(a, b) : this._(a, b);

           C._(a, b);

         }

@@ -3281,24 +4255,93 @@
   ],

 };

 

+const List<VisitKind> UNTESTABLE_KINDS = const <VisitKind>[

+  VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,

+  VisitKind.VISIT_STATIC_METHOD_SETTER_PREFIX,

+  VisitKind.VISIT_STATIC_METHOD_SETTER_POSTFIX,

+  VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,

+  VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,

+  VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,

+  VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,

+  VisitKind.VISIT_SUPER_FIELD_FIELD_PREFIX,

+  VisitKind.VISIT_SUPER_FIELD_FIELD_POSTFIX,

+  VisitKind.VISIT_SUPER_METHOD_SETTER_COMPOUND,

+  VisitKind.VISIT_SUPER_METHOD_SETTER_PREFIX,

+  VisitKind.VISIT_SUPER_METHOD_SETTER_POSTFIX,

+  VisitKind.VISIT_CLASS_TYPE_LITERAL_SET,

+  VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET,

+  VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,

+  VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET,

+  VisitKind.VISIT_FINAL_PARAMETER_SET,

+  VisitKind.VISIT_FINAL_LOCAL_VARIABLE_SET,

+  VisitKind.VISIT_LOCAL_FUNCTION_SET,

+  VisitKind.VISIT_STATIC_GETTER_SET,

+  VisitKind.VISIT_STATIC_SETTER_GET,

+  VisitKind.VISIT_STATIC_SETTER_INVOKE,

+  VisitKind.VISIT_FINAL_STATIC_FIELD_SET,

+  VisitKind.VISIT_STATIC_FUNCTION_SET,

+  VisitKind.VISIT_FINAL_TOP_LEVEL_FIELD_SET,

+  VisitKind.VISIT_TOP_LEVEL_GETTER_SET,

+  VisitKind.VISIT_TOP_LEVEL_SETTER_GET,

+  VisitKind.VISIT_TOP_LEVEL_SETTER_INVOKE,

+  VisitKind.VISIT_TOP_LEVEL_FUNCTION_SET,

+  VisitKind.VISIT_FINAL_SUPER_FIELD_SET,

+  VisitKind.VISIT_SUPER_GETTER_SET,

+  VisitKind.VISIT_SUPER_SETTER_GET,

+  VisitKind.VISIT_SUPER_SETTER_INVOKE,

+  VisitKind.VISIT_SUPER_METHOD_SET,

+];

+

 main(List<String> arguments) {

+  Set<VisitKind> kinds = new Set<VisitKind>.from(VisitKind.values);

   asyncTest(() => Future.forEach([

     () {

       return test(

+          kinds,

           arguments,

           SEND_TESTS,

           (elements) => new SemanticSendTestVisitor(elements));

     },

     () {

       return test(

+          kinds,

           arguments,

           DECL_TESTS,

           (elements) => new SemanticDeclarationTestVisitor(elements));

     },

+    () {

+      Set<VisitKind> unvisitedKindSet =

+          kinds.toSet()..removeAll(UNTESTABLE_KINDS);

+      List<VisitKind> unvisitedKindList = unvisitedKindSet.toList();

+      unvisitedKindList..sort((a, b) => a.index.compareTo(b.index));

+

+      Expect.isTrue(unvisitedKindList.isEmpty,

+          "Untested visit kinds:\n  ${unvisitedKindList.join(',\n  ')},\n");

+

+      Set<VisitKind> testedUntestableKinds =

+          UNTESTABLE_KINDS.toSet()..removeAll(kinds);

+      Expect.isTrue(testedUntestableKinds.isEmpty,

+          "Tested untestable visit kinds (remove from UNTESTABLE_KINDS):\n  "

+          "${testedUntestableKinds.join(',\n  ')},\n");

+    },

+    () {

+      ClassMirror mirror1 = reflectType(SemanticSendTestVisitor);

+      Set<Symbol> symbols1 = mirror1.declarations.keys.toSet();

+      ClassMirror mirror2 = reflectType(SemanticSendVisitor);

+      Set<Symbol> symbols2 =

+          mirror2.declarations.values

+              .where((m) => m is MethodMirror &&

+                            !m.isConstructor &&

+                            m.simpleName != #apply)

+              .map((m) => m.simpleName).toSet();

+      symbols2.removeAll(symbols1);

+      print("Untested visit methods:\n  ${symbols2.join(',\n  ')},\n");

+    }

   ], (f) => f()));

 }

 

-Future test(List<String> arguments,

+Future test(Set<VisitKind> unvisitedKinds,

+            List<String> arguments,

             Map<String, List<Test>> TESTS,

             SemanticTestVisitor createVisitor(TreeElements elements)) {

   Map<String, String> sourceFiles = {};

@@ -3367,6 +4410,7 @@
         Expect.listEquals(expectedVisits, visitor.visits,

             "In test:\n"

             "${library.compilationUnit.script.text}");

+        unvisitedKinds.removeAll(visitor.visits.map((visit) => visit.method));

       }

       if (element.isAbstractField) {

         AbstractFieldElement abstractFieldElement = element;

@@ -3419,14 +4463,6 @@
   }

 

   @override

-  errorInvalidAssert(

-      Send node,

-      NodeList arguments,

-      arg) {

-    // TODO: implement errorAssert

-  }

-

-  @override

   visitBinary(

       Send node,

       Node left,

@@ -3473,14 +4509,14 @@
   }

 

   @override

-  errorClassTypeLiteralSet(

+  visitClassTypeLiteralSet(

       SendSet node,

       ConstantExpression constant,

       Node rhs,

       arg) {

     visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,

         constant: constant.getText(), rhs: rhs));

-    apply(rhs, arg);

+    super.visitClassTypeLiteralSet(node, constant, rhs, arg);

   }

 

   @override

@@ -3556,7 +4592,7 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,

         receiver: receiver, name: selector.name, rhs: rhs));

-    apply(receiver, arg);

+    super.visitDynamicPropertySet(node, receiver, selector, rhs, arg);

   }

 

   @override

@@ -3580,14 +4616,14 @@
   }

 

   @override

-  errorDynamicTypeLiteralSet(

+  visitDynamicTypeLiteralSet(

       Send node,

       ConstantExpression constant,

       Node rhs,

       arg) {

     visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET,

         rhs: rhs));

-    apply(rhs, arg);

+    super.visitDynamicTypeLiteralSet(node, constant, rhs, arg);

   }

 

   @override

@@ -3657,6 +4693,17 @@
   }

 

   @override

+  visitLocalFunctionSet(

+      SendSet node,

+      LocalFunctionElement function,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_SET,

+        element: function, rhs: rhs));

+    super.visitLocalFunctionSet(node, function, rhs, arg);

+  }

+

+  @override

   visitLocalFunctionInvoke(

       Send node,

       LocalFunctionElement function,

@@ -3697,7 +4744,18 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_SET,

         element: variable, rhs: rhs));

-    apply(rhs, arg);

+    super.visitLocalVariableSet(node, variable, rhs, arg);

+  }

+

+  @override

+  visitFinalLocalVariableSet(

+      SendSet node,

+      LocalVariableElement variable,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_SET,

+        element: variable, rhs: rhs));

+    super.visitFinalLocalVariableSet(node, variable, rhs, arg);

   }

 

   @override

@@ -3728,7 +4786,18 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_PARAMETER_SET,

                          element: parameter, rhs: rhs));

-    apply(rhs, arg);

+    super.visitParameterSet(node, parameter, rhs, arg);

+  }

+

+  @override

+  visitFinalParameterSet(

+      SendSet node,

+      ParameterElement parameter,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_SET,

+                         element: parameter, rhs: rhs));

+    super.visitFinalParameterSet(node, parameter, rhs, arg);

   }

 

   @override

@@ -3759,7 +4828,18 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_SET,

         element: field, rhs: rhs));

-    apply(rhs, arg);

+    super.visitStaticFieldSet(node, field, rhs, arg);

+  }

+

+  @override

+  visitFinalStaticFieldSet(

+      SendSet node,

+      FieldElement field,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_FINAL_STATIC_FIELD_SET,

+        element: field, rhs: rhs));

+    super.visitFinalStaticFieldSet(node, field, rhs, arg);

   }

 

   @override

@@ -3772,6 +4852,17 @@
   }

 

   @override

+  visitStaticFunctionSet(

+      SendSet node,

+      MethodElement function,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_SET,

+        element: function, rhs: rhs));

+    super.visitStaticFunctionSet(node, function, rhs, arg);

+  }

+

+  @override

   visitStaticFunctionInvoke(

       Send node,

       MethodElement function,

@@ -3780,7 +4871,8 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,

         element: function, arguments: arguments));

-    apply(arguments, arg);

+    super.visitStaticFunctionInvoke(

+        node, function, arguments, callStructure, arg);

   }

 

   @override

@@ -3802,6 +4894,18 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_GET,

         element: getter));

+    super.visitStaticGetterGet(node, getter, arg);

+  }

+

+  @override

+  visitStaticGetterSet(

+      SendSet node,

+      MethodElement getter,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SET,

+        element: getter, rhs: rhs));

+    super.visitStaticGetterSet(node, getter, rhs, arg);

   }

 

   @override

@@ -3813,7 +4917,29 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,

         element: getter, arguments: arguments));

-    apply(arguments, arg);

+    super.visitStaticGetterInvoke(node, getter, arguments, callStructure, arg);

+  }

+

+  @override

+  visitStaticSetterInvoke(

+      Send node,

+      FunctionElement setter,

+      NodeList arguments,

+      CallStructure callStructure,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,

+        element: setter, arguments: arguments));

+    super.visitStaticSetterInvoke(node, setter, arguments, callStructure, arg);

+  }

+

+  @override

+  visitStaticSetterGet(

+      Send node,

+      FunctionElement getter,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_GET,

+        element: getter));

+    super.visitStaticSetterGet(node, getter, arg);

   }

 

   @override

@@ -3824,7 +4950,7 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_SET,

         element: setter, rhs: rhs));

-    apply(rhs, arg);

+    super.visitStaticSetterSet(node, setter, rhs, arg);

   }

 

   @override

@@ -3851,7 +4977,6 @@
     apply(argument, arg);

   }

 

-

   @override

   visitSuperIndex(

       Send node,

@@ -3959,7 +5084,18 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,

         element: field, rhs: rhs));

-    apply(rhs, arg);

+    super.visitTopLevelFieldSet(node, field, rhs, arg);

+  }

+

+  @override

+  visitFinalTopLevelFieldSet(

+      SendSet node,

+      FieldElement field,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_FINAL_TOP_LEVEL_FIELD_SET,

+        element: field, rhs: rhs));

+    super.visitFinalTopLevelFieldSet(node, field, rhs, arg);

   }

 

   @override

@@ -3972,6 +5108,17 @@
   }

 

   @override

+  visitTopLevelFunctionSet(

+      SendSet node,

+      MethodElement function,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_SET,

+        element: function, rhs: rhs));

+    super.visitTopLevelFunctionSet(node, function, rhs, arg);

+  }

+

+  @override

   visitTopLevelFunctionInvoke(

       Send node,

       MethodElement function,

@@ -4002,6 +5149,17 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,

         element: getter));

+    super.visitTopLevelGetterGet(node, getter, arg);

+  }

+

+  @override

+  visitTopLevelSetterGet(

+      Send node,

+      FunctionElement setter,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_GET,

+        element: setter));

+    super.visitTopLevelSetterGet(node, setter, arg);

   }

 

   @override

@@ -4013,7 +5171,32 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,

         element: getter, arguments: arguments));

-    apply(arguments, arg);

+    super.visitTopLevelGetterInvoke(

+        node, getter, arguments, callStructure, arg);

+  }

+

+  @override

+  visitTopLevelSetterInvoke(

+      Send node,

+      FunctionElement setter,

+      NodeList arguments,

+      CallStructure callStructure,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_INVOKE,

+        element: setter, arguments: arguments));

+    super.visitTopLevelSetterInvoke(

+        node, setter, arguments, callStructure, arg);

+  }

+

+  @override

+  visitTopLevelGetterSet(

+      SendSet node,

+      FunctionElement getter,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SET,

+        element: getter, rhs: rhs));

+    super.visitTopLevelGetterSet(node, getter, rhs, arg);

   }

 

   @override

@@ -4024,7 +5207,7 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,

         element: setter, rhs: rhs));

-    apply(rhs, arg);

+    super.visitTopLevelSetterSet(node, setter, rhs, arg);

   }

 

   @override

@@ -4049,14 +5232,14 @@
   }

 

   @override

-  errorTypeVariableTypeLiteralSet(

+  visitTypeVariableTypeLiteralSet(

       SendSet node,

       TypeVariableElement element,

       Node rhs,

       arg) {

     visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,

         element: element, rhs: rhs));

-    apply(rhs, arg);

+    super.visitTypeVariableTypeLiteralSet(node, element, rhs, arg);

   }

 

   @override

@@ -4081,14 +5264,14 @@
   }

 

   @override

-  errorTypedefTypeLiteralSet(

+  visitTypedefTypeLiteralSet(

       SendSet node,

       ConstantExpression constant,

       Node rhs,

       arg) {

     visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET,

         constant: constant.getText(), rhs: rhs));

-    apply(rhs, arg);

+    super.visitTypedefTypeLiteralSet(node, constant, rhs, arg);

   }

 

   @override

@@ -4159,7 +5342,18 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SET,

         element: field, rhs: rhs));

-    apply(rhs, arg);

+    super.visitSuperFieldSet(node, field, rhs, arg);

+  }

+

+  @override

+  visitFinalSuperFieldSet(

+      SendSet node,

+      FieldElement field,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_FINAL_SUPER_FIELD_SET,

+        element: field, rhs: rhs));

+    super.visitFinalSuperFieldSet(node, field, rhs, arg);

   }

 

   @override

@@ -4171,6 +5365,17 @@
   }

 

   @override

+  visitSuperMethodSet(

+      SendSet node,

+      MethodElement method,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SET,

+        element: method, rhs: rhs));

+    super.visitSuperMethodSet(node, method, rhs, arg);

+  }

+

+  @override

   visitSuperMethodInvoke(

       Send node,

       MethodElement method,

@@ -4200,6 +5405,16 @@
       FunctionElement getter,

       arg) {

     visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_GET, element: getter));

+    super.visitSuperGetterGet(node, getter, arg);

+  }

+

+  @override

+  visitSuperSetterGet(

+      Send node,

+      FunctionElement setter,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_GET, element: setter));

+    super.visitSuperSetterGet(node, setter, arg);

   }

 

   @override

@@ -4211,7 +5426,30 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,

         element: getter, arguments: arguments));

-    apply(arguments, arg);

+    super.visitSuperGetterInvoke(node, getter, arguments, callStructure, arg);

+  }

+

+  @override

+  visitSuperSetterInvoke(

+      Send node,

+      FunctionElement setter,

+      NodeList arguments,

+      CallStructure callStructure,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_INVOKE,

+        element: setter, arguments: arguments));

+    super.visitSuperSetterInvoke(node, setter, arguments, callStructure, arg);

+  }

+

+  @override

+  visitSuperGetterSet(

+      SendSet node,

+      FunctionElement getter,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SET,

+        element: getter, rhs: rhs));

+    super.visitSuperGetterSet(node, getter, rhs, arg);

   }

 

   @override

@@ -4222,7 +5460,7 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_SET,

         element: setter, rhs: rhs));

-    apply(rhs, arg);

+    super.visitSuperSetterSet(node, setter, rhs, arg);

   }

 

   @override

@@ -4295,168 +5533,6 @@
   }

 

   @override

-  errorFinalLocalVariableSet(

-      SendSet node,

-      LocalVariableElement variable,

-      Node rhs,

-      arg) {

-    // TODO: implement errorFinalLocalVariableSet

-  }

-

-  @override

-  errorFinalParameterSet(

-      SendSet node,

-      ParameterElement parameter,

-      Node rhs,

-      arg) {

-    // TODO: implement errorFinalParameterSet

-  }

-

-  @override

-  errorFinalStaticFieldSet(

-      SendSet node,

-      FieldElement field,

-      Node rhs,

-      arg) {

-    // TODO: implement errorFinalStaticFieldSet

-  }

-

-  @override

-  errorFinalSuperFieldSet(

-      SendSet node,

-      FieldElement field,

-      Node rhs,

-      arg) {

-    // TODO: implement errorFinalSuperFieldSet

-  }

-

-  @override

-  errorFinalTopLevelFieldSet(

-      SendSet node,

-      FieldElement field,

-      Node rhs,

-      arg) {

-    // TODO: implement errorFinalTopLevelFieldSet

-  }

-

-  @override

-  errorLocalFunctionSet(

-      SendSet node,

-      LocalFunctionElement function,

-      Node rhs,

-      arg) {

-    // TODO: implement errorLocalFunctionSet

-  }

-

-  @override

-  errorStaticFunctionSet(

-      Send node,

-      MethodElement function,

-      Node rhs,

-      arg) {

-    // TODO: implement errorStaticFunctionSet

-  }

-

-  @override

-  errorStaticGetterSet(

-      SendSet node,

-      FunctionElement getter,

-      Node rhs,

-      arg) {

-    // TODO: implement errorStaticGetterSet

-  }

-

-  @override

-  errorStaticSetterGet(

-      Send node,

-      FunctionElement setter,

-      arg) {

-    // TODO: implement errorStaticSetterGet

-  }

-

-  @override

-  errorStaticSetterInvoke(

-      Send node,

-      FunctionElement setter,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    // TODO: implement errorStaticSetterInvoke

-  }

-

-  @override

-  errorSuperGetterSet(

-      SendSet node,

-      FunctionElement getter,

-      Node rhs,

-      arg) {

-    // TODO: implement errorSuperGetterSet

-  }

-

-  @override

-  errorSuperMethodSet(

-      Send node,

-      MethodElement method,

-      Node rhs,

-      arg) {

-    // TODO: implement errorSuperMethodSet

-  }

-

-  @override

-  errorSuperSetterGet(

-      Send node,

-      FunctionElement setter,

-      arg) {

-    // TODO: implement errorSuperSetterGet

-  }

-

-  @override

-  errorSuperSetterInvoke(

-      Send node,

-      FunctionElement setter,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    // TODO: implement errorSuperSetterInvoke

-  }

-

-  @override

-  errorTopLevelFunctionSet(

-      Send node,

-      MethodElement function,

-      Node rhs,

-      arg) {

-    // TODO: implement errorTopLevelFunctionSet

-  }

-

-  @override

-  errorTopLevelGetterSet(

-      SendSet node,

-      FunctionElement getter,

-      Node rhs,

-      arg) {

-    // TODO: implement errorTopLevelGetterSet

-  }

-

-  @override

-  errorTopLevelSetterGet(

-      Send node,

-      FunctionElement setter,

-      arg) {

-    // TODO: implement errorTopLevelSetterGet

-  }

-

-  @override

-  errorTopLevelSetterInvoke(

-      Send node,

-      FunctionElement setter,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    // TODO: implement errorTopLevelSetterInvoke

-  }

-

-  @override

   visitDynamicPropertyCompound(

       Send node,

       Node receiver,

@@ -4473,63 +5549,155 @@
   }

 

   @override

-  errorFinalLocalVariableCompound(

+  visitFinalLocalVariableCompound(

       Send node,

       LocalVariableElement variable,

       AssignmentOperator operator,

       Node rhs,

       arg) {

-    // TODO: implement errorFinalLocalVariableCompound

+    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,

+        element: variable, operator: operator, rhs: rhs));

+    apply(rhs, arg);

   }

 

   @override

-  errorFinalParameterCompound(

+  visitFinalLocalVariablePrefix(

+      Send node,

+      LocalVariableElement variable,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_PREFIX,

+        element: variable, operator: operator));

+  }

+

+  @override

+  visitFinalLocalVariablePostfix(

+      Send node,

+      LocalVariableElement variable,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,

+        element: variable, operator: operator));

+  }

+

+  @override

+  visitFinalParameterCompound(

       Send node,

       ParameterElement parameter,

       AssignmentOperator operator,

       Node rhs,

       arg) {

-    // TODO: implement errorFinalParameterCompound

+    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_COMPOUND,

+        element: parameter, operator: operator, rhs: rhs));

+    apply(rhs, arg);

   }

 

   @override

-  errorFinalStaticFieldCompound(

+  visitFinalParameterPrefix(

+      Send node,

+      ParameterElement parameter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_PREFIX,

+        element: parameter, operator: operator));

+  }

+

+  @override

+  visitFinalParameterPostfix(

+      Send node,

+      ParameterElement parameter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_POSTFIX,

+        element: parameter, operator: operator));

+  }

+

+  @override

+  visitFinalStaticFieldCompound(

       Send node,

       FieldElement field,

       AssignmentOperator operator,

       Node rhs,

       arg) {

-    // TODO: implement errorFinalStaticFieldCompound

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_COMPOUND,

+        element: field, operator: operator, rhs: rhs));

+    apply(rhs, arg);

   }

 

   @override

-  errorFinalSuperFieldCompound(

+  visitFinalStaticFieldPostfix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_POSTFIX,

+        element: field, operator: operator));

+  }

+

+  @override

+  visitFinalStaticFieldPrefix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_PREFIX,

+        element: field, operator: operator));

+  }

+

+  @override

+  visitFinalSuperFieldCompound(

       Send node,

       FieldElement field,

       AssignmentOperator operator,

       Node rhs,

       arg) {

-    // TODO: implement errorFinalSuperFieldCompound

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_COMPOUND,

+        element: field, operator: operator, rhs: rhs));

+    apply(rhs, arg);

   }

 

   @override

-  errorFinalTopLevelFieldCompound(

+  visitFinalTopLevelFieldCompound(

       Send node,

       FieldElement field,

       AssignmentOperator operator,

       Node rhs,

       arg) {

-    // TODO: implement errorFinalTopLevelFieldCompound

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,

+        element: field, operator: operator, rhs: rhs));

+    apply(rhs, arg);

   }

 

   @override

-  errorLocalFunctionCompound(

+  visitFinalTopLevelFieldPostfix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,

+        element: field, operator: operator));

+  }

+

+  @override

+  visitFinalTopLevelFieldPrefix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,

+        element: field, operator: operator));

+  }

+

+  @override

+  visitLocalFunctionCompound(

       Send node,

       LocalFunctionElement function,

       AssignmentOperator operator,

       Node rhs,

       arg) {

-    // TODO: implement errorLocalFunctionCompound

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_COMPOUND,

+        element: function, operator: operator, rhs: rhs));

+    apply(rhs, arg);

   }

 

   @override

@@ -4698,7 +5866,73 @@
       AssignmentOperator operator,

       Node rhs,

       arg) {

-    // TODO: implement visitSuperMethodSetterCompound

+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_COMPOUND,

+        getter: method, setter: setter, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperMethodCompound(

+      Send node,

+      FunctionElement method,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_COMPOUND,

+        element: method, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperMethodPrefix(

+      Send node,

+      FunctionElement method,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_PREFIX,

+        element: method, operator: operator));

+  }

+

+  @override

+  visitSuperMethodPostfix(

+      Send node,

+      FunctionElement method,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_POSTFIX,

+        element: method, operator: operator));

+  }

+

+  @override

+  visitUnresolvedSuperCompound(

+      Send node,

+      Element element,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND,

+        operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitUnresolvedSuperPrefix(

+      Send node,

+      Element element,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_PREFIX,

+        operator: operator));

+  }

+

+  @override

+  visitUnresolvedSuperPostfix(

+      Send node,

+      Element element,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_POSTFIX,

+        operator: operator));

   }

 

   @override

@@ -4709,7 +5943,9 @@
       AssignmentOperator operator,

       Node rhs,

       arg) {

-    // TODO: implement visitTopLevelMethodSetterCompound

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,

+        getter: method, setter: setter, operator: operator, rhs: rhs));

+    apply(rhs, arg);

   }

 

   @override

@@ -4744,79 +5980,80 @@
   }

 

   @override

-  errorClassTypeLiteralCompound(

+  visitClassTypeLiteralCompound(

       Send node,

       ConstantExpression constant,

       AssignmentOperator operator,

       Node rhs,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_CLASS_TYPE_LITERAL_COMPOUND,

+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,

         constant: constant.getText(), operator: operator, rhs: rhs));

     apply(rhs, arg);

   }

 

   @override

-  errorDynamicTypeLiteralCompound(

+  visitDynamicTypeLiteralCompound(

       Send node,

       ConstantExpression constant,

       AssignmentOperator operator,

       Node rhs,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_DYNAMIC_TYPE_LITERAL_COMPOUND,

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,

         constant: constant.getText(), operator: operator, rhs: rhs));

     apply(rhs, arg);

   }

 

   @override

-  errorTypeVariableTypeLiteralCompound(

+  visitTypeVariableTypeLiteralCompound(

       Send node,

       TypeVariableElement element,

       AssignmentOperator operator,

       Node rhs,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

         element: element, operator: operator, rhs: rhs));

     apply(rhs, arg);

   }

 

   @override

-  errorTypedefTypeLiteralCompound(

+  visitTypedefTypeLiteralCompound(

       Send node,

       ConstantExpression constant,

       AssignmentOperator operator,

       Node rhs,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_TYPEDEF_TYPE_LITERAL_COMPOUND,

+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,

         constant: constant.getText(), operator: operator, rhs: rhs));

     apply(rhs, arg);

   }

 

   @override

-  errorLocalFunctionPrefix(

+  visitLocalFunctionPrefix(

       Send node,

       LocalFunctionElement function,

       IncDecOperator operator,

       arg) {

-    // TODO: implement errorLocalFunctionPrefix

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_PREFIX,

+        element: function, operator: operator));

   }

 

   @override

-  errorClassTypeLiteralPrefix(

+  visitClassTypeLiteralPrefix(

       Send node,

       ConstantExpression constant,

       IncDecOperator operator,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_CLASS_TYPE_LITERAL_PREFIX,

+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,

         constant: constant.getText(), operator: operator));

   }

 

   @override

-  errorDynamicTypeLiteralPrefix(

+  visitDynamicTypeLiteralPrefix(

       Send node,

       ConstantExpression constant,

       IncDecOperator operator,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_DYNAMIC_TYPE_LITERAL_PREFIX,

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,

         constant: constant.getText(), operator: operator));

   }

 

@@ -4868,7 +6105,21 @@
       FunctionElement setter,

       IncDecOperator operator,

       arg) {

-    // TODO: implement visitStaticMethodSetterPrefix

+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_PREFIX,

+        getter: getter, setter: setter, operator: operator));

+  }

+

+  @override

+  visitSuperFieldFieldCompound(

+      Send node,

+      FieldElement readField,

+      FieldElement writtenField,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,

+        getter: readField, setter: writtenField, operator: operator, rhs: rhs));

+    apply(rhs, arg);

   }

 

   @override

@@ -4878,7 +6129,8 @@
       FieldElement writtenField,

       IncDecOperator operator,

       arg) {

-    // TODO: implement visitSuperFieldFieldPrefix

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_PREFIX,

+        getter: readField, setter: writtenField, operator: operator));

   }

 

   @override

@@ -4892,6 +6144,16 @@
   }

 

   @override

+  visitFinalSuperFieldPrefix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_PREFIX,

+        element: field, operator: operator));

+  }

+

+  @override

   visitSuperFieldSetterPrefix(

       Send node,

       FieldElement field,

@@ -4931,7 +6193,8 @@
       FunctionElement setter,

       IncDecOperator operator,

       arg) {

-    // TODO: implement visitSuperMethodSetterPrefix

+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_PREFIX,

+        getter: method, setter: setter, operator: operator));

   }

 

   @override

@@ -4974,55 +6237,57 @@
       FunctionElement setter,

       IncDecOperator operator,

       arg) {

-    // TODO: implement visitTopLevelMethodSetterPrefix

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,

+        getter: method, setter: setter, operator: operator));

   }

 

   @override

-  errorTypeVariableTypeLiteralPrefix(

+  visitTypeVariableTypeLiteralPrefix(

       Send node,

       TypeVariableElement element,

       IncDecOperator operator,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,

+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,

         element: element, operator: operator));

   }

 

   @override

-  errorTypedefTypeLiteralPrefix(

+  visitTypedefTypeLiteralPrefix(

       Send node,

       ConstantExpression constant,

       IncDecOperator operator,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_TYPEDEF_TYPE_LITERAL_PREFIX,

+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,

         constant: constant.getText(), operator: operator));

   }

 

   @override

-  errorLocalFunctionPostfix(

+  visitLocalFunctionPostfix(

       Send node,

       LocalFunctionElement function,

       IncDecOperator operator,

       arg) {

-    // TODO: implement errorLocalFunctionPostfix

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_POSTFIX,

+        element: function, operator: operator));

   }

 

   @override

-  errorClassTypeLiteralPostfix(

+  visitClassTypeLiteralPostfix(

       Send node,

       ConstantExpression constant,

       IncDecOperator operator,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_CLASS_TYPE_LITERAL_POSTFIX,

+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_POSTFIX,

         constant: constant.getText(), operator: operator));

   }

 

   @override

-  errorDynamicTypeLiteralPostfix(

+  visitDynamicTypeLiteralPostfix(

       Send node,

       ConstantExpression constant,

       IncDecOperator operator,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_DYNAMIC_TYPE_LITERAL_POSTFIX,

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,

         constant: constant.getText(), operator: operator));

   }

 

@@ -5074,7 +6339,8 @@
       FunctionElement setter,

       IncDecOperator operator,

       arg) {

-    // TODO: implement visitStaticMethodSetterPostfix

+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_POSTFIX,

+        getter: getter, setter: setter, operator: operator));

   }

 

   @override

@@ -5084,7 +6350,8 @@
       FieldElement writtenField,

       IncDecOperator operator,

       arg) {

-    // TODO: implement visitSuperFieldFieldPostfix

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_POSTFIX,

+        getter: readField, setter: writtenField, operator: operator));

   }

 

   @override

@@ -5098,6 +6365,16 @@
   }

 

   @override

+  visitFinalSuperFieldPostfix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_POSTFIX,

+        element: field, operator: operator));

+  }

+

+  @override

   visitSuperFieldSetterPostfix(

       Send node,

       FieldElement field,

@@ -5137,7 +6414,8 @@
       FunctionElement setter,

       IncDecOperator operator,

       arg) {

-    // TODO: implement visitSuperMethodSetterPostfix

+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_POSTFIX,

+        getter: method, setter: setter, operator: operator));

   }

 

   @override

@@ -5180,55 +6458,40 @@
       FunctionElement setter,

       IncDecOperator operator,

       arg) {

-    // TODO: implement visitTopLevelMethodSetterPostfix

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,

+        getter: method, setter: setter, operator: operator));

   }

 

   @override

-  errorTypeVariableTypeLiteralPostfix(

+  visitTypeVariableTypeLiteralPostfix(

       Send node,

       TypeVariableElement element,

       IncDecOperator operator,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,

+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,

         element: element, operator: operator));

   }

 

   @override

-  errorTypedefTypeLiteralPostfix(

+  visitTypedefTypeLiteralPostfix(

       Send node,

       ConstantExpression constant,

       IncDecOperator operator,

       arg) {

-    visits.add(new Visit(VisitKind.ERROR_TYPEDEF_TYPE_LITERAL_POSTFIX,

+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,

         constant: constant.getText(), operator: operator));

   }

 

   @override

-  visitConstantGet(

-      Send node,

-      ConstantExpression constant,

-      arg) {

-    // TODO: implement visitConstantGet

-  }

-

-  @override

-  visitConstantInvoke(

-      Send node,

-      ConstantExpression constant,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    // TODO: implement visitConstantInvoke

-  }

-

-  @override

-  errorUnresolvedCompound(

+  visitUnresolvedCompound(

       Send node,

       ErroneousElement element,

       AssignmentOperator operator,

       Node rhs,

       arg) {

-    // TODO: implement errorUnresolvedCompound

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_COMPOUND,

+        operator: operator, rhs: rhs));

+    apply(rhs, arg);

   }

 

   @override

@@ -5240,6 +6503,17 @@
   }

 

   @override

+  visitUnresolvedSet(

+      Send node,

+      Element element,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SET,

+                         name: element.name, rhs: rhs));

+    super.visitUnresolvedSet(node, element, rhs, arg);

+  }

+

+  @override

   visitUnresolvedInvoke(

       Send node,

       Element element,

@@ -5247,58 +6521,32 @@
       Selector selector,

       arg) {

     visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

-        name: element.name, arguments: arguments));

+                         name: element.name, arguments: arguments));

+    super.visitUnresolvedInvoke(node, element, arguments, selector, arg);

   }

 

   @override

-  errorUnresolvedPostfix(

+  visitUnresolvedPostfix(

       Send node,

       ErroneousElement element,

       IncDecOperator operator,

       arg) {

     visits.add(new Visit(

-        VisitKind.ERROR_UNRESOLVED_POSTFIX, operator: operator));

+        VisitKind.VISIT_UNRESOLVED_POSTFIX, operator: operator));

   }

 

   @override

-  errorUnresolvedPrefix(

+  visitUnresolvedPrefix(

       Send node,

       ErroneousElement element,

       IncDecOperator operator,

       arg) {

-    // TODO: implement errorUnresolvedPrefix

+    visits.add(new Visit(

+        VisitKind.VISIT_UNRESOLVED_PREFIX, operator: operator));

   }

 

   @override

-  errorUnresolvedSet(

-      Send node,

-      ErroneousElement element,

-      Node rhs,

-      arg) {

-    // TODO: implement errorUnresolvedSet

-  }

-

-  @override

-  errorUndefinedBinaryExpression(

-      Send node,

-      Node left,

-      Operator operator,

-      Node right,

-      arg) {

-    // TODO: implement errorUndefinedBinaryExpression

-  }

-

-  @override

-  errorUndefinedUnaryExpression(

-      Send node,

-      Operator operator,

-      Node expression,

-      arg) {

-    // TODO: implement errorUndefinedUnaryExpression

-  }

-

-  @override

-  visitUnresolvedSuperGetterCompoundIndexSet(

+  visitUnresolvedSuperCompoundIndexSet(

       Send node,

       Element element,

       Node index,

@@ -5306,13 +6554,29 @@
       Node rhs,

       arg) {

     visits.add(new Visit(

-        VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,

+        VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,

         index: index, operator: operator, rhs: rhs));

     apply(index, arg);

     apply(rhs, arg);

   }

 

   @override

+  visitUnresolvedSuperGetterCompoundIndexSet(

+      Send node,

+      Element element,

+      MethodElement setter,

+      Node index,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(

+        VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,

+        setter: setter, index: index, operator: operator, rhs: rhs));

+    apply(index, arg);

+    apply(rhs, arg);

+  }

+

+  @override

   visitUnresolvedSuperSetterCompoundIndexSet(

       Send node,

       MethodElement getter,

@@ -5342,18 +6606,31 @@
   }

 

   @override

-  visitUnresolvedSuperGetterIndexPostfix(

+  visitUnresolvedSuperIndexPostfix(

       Send node,

       Element element,

       Node index,

       IncDecOperator operator,

       arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,

                index: index, operator: operator));

     apply(index, arg);

   }

 

   @override

+  visitUnresolvedSuperGetterIndexPostfix(

+      Send node,

+      Element element,

+      MethodElement setter,

+      Node index,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,

+               setter: setter, index: index, operator: operator));

+    apply(index, arg);

+  }

+

+  @override

   visitUnresolvedSuperSetterIndexPostfix(

       Send node,

       MethodElement getter,

@@ -5367,18 +6644,31 @@
   }

 

   @override

-  visitUnresolvedSuperGetterIndexPrefix(

+  visitUnresolvedSuperIndexPrefix(

       Send node,

       Element element,

       Node index,

       IncDecOperator operator,

       arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,

                index: index, operator: operator));

     apply(index, arg);

   }

 

   @override

+  visitUnresolvedSuperGetterIndexPrefix(

+      Send node,

+      Element element,

+      MethodElement setter,

+      Node index,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,

+               setter: setter, index: index, operator: operator));

+    apply(index, arg);

+  }

+

+  @override

   visitUnresolvedSuperSetterIndexPrefix(

       Send node,

       MethodElement getter,

@@ -5589,6 +6879,278 @@
         selector: callStructure));

     apply(arguments, arg);

   }

+

+  @override

+  visitUnresolvedStaticGetterCompound(

+      Send node,

+      Element element,

+      MethodElement setter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,

+        setter: setter, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitUnresolvedTopLevelGetterCompound(

+      Send node,

+      Element element,

+      MethodElement setter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,

+        setter: setter, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitUnresolvedStaticSetterCompound(

+      Send node,

+      MethodElement getter,

+      Element element,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,

+        getter: getter, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitUnresolvedTopLevelSetterCompound(

+      Send node,

+      MethodElement getter,

+      Element element,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,

+        getter: getter, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitStaticMethodCompound(

+      Send node,

+      MethodElement method,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_COMPOUND,

+        element: method, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitTopLevelMethodCompound(

+      Send node,

+      MethodElement method,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_COMPOUND,

+        element: method, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitUnresolvedStaticGetterPrefix(

+      Send node,

+      Element element,

+      MethodElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,

+        setter: setter, operator: operator));

+  }

+

+  @override

+  visitUnresolvedTopLevelGetterPrefix(

+      Send node,

+      Element element,

+      MethodElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,

+        setter: setter, operator: operator));

+  }

+

+  @override

+  visitUnresolvedStaticSetterPrefix(

+      Send node,

+      MethodElement getter,

+      Element element,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,

+        getter: getter, operator: operator));

+  }

+

+  @override

+  visitUnresolvedTopLevelSetterPrefix(

+      Send node,

+      MethodElement getter,

+      Element element,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,

+        getter: getter, operator: operator));

+  }

+

+  @override

+  visitStaticMethodPrefix(

+      Send node,

+      MethodElement method,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_PREFIX,

+        element: method, operator: operator));

+  }

+

+  @override

+  visitTopLevelMethodPrefix(

+      Send node,

+      MethodElement method,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_PREFIX,

+        element: method, operator: operator));

+  }

+

+  @override

+  visitUnresolvedStaticGetterPostfix(

+      Send node,

+      Element element,

+      MethodElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,

+        setter: setter, operator: operator));

+  }

+

+  @override

+  visitUnresolvedTopLevelGetterPostfix(

+      Send node,

+      Element element,

+      MethodElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,

+        setter: setter, operator: operator));

+  }

+

+  @override

+  visitUnresolvedStaticSetterPostfix(

+      Send node,

+      MethodElement getter,

+      Element element,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,

+        getter: getter, operator: operator));

+  }

+

+  @override

+  visitUnresolvedTopLevelSetterPostfix(

+      Send node,

+      MethodElement getter,

+      Element element,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,

+        getter: getter, operator: operator));

+  }

+

+  @override

+  visitStaticMethodPostfix(

+      Send node,

+      MethodElement method,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_POSTFIX,

+        element: method, operator: operator));

+  }

+

+  @override

+  visitTopLevelMethodPostfix(

+      Send node,

+      MethodElement method,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_POSTFIX,

+        element: method, operator: operator));

+  }

+

+  @override

+  visitUnresolvedSuperGetterCompound(

+      Send node, Element element,

+      MethodElement setter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,

+        setter: setter, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitUnresolvedSuperGetterPostfix(

+      Send node,

+      Element element,

+      MethodElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,

+        setter: setter, operator: operator));

+  }

+

+  @override

+  visitUnresolvedSuperGetterPrefix(

+      Send node,

+      Element element,

+      MethodElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,

+        setter: setter, operator: operator));

+  }

+

+  @override

+  visitUnresolvedSuperSetterCompound(

+      Send node, MethodElement getter,

+      Element element,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,

+        getter: getter, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitUnresolvedSuperSetterPostfix(

+      Send node,

+      MethodElement getter,

+      Element element,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,

+        getter: getter, operator: operator));

+  }

+

+  @override

+  visitUnresolvedSuperSetterPrefix(

+      Send node,

+      MethodElement getter,

+      Element element,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,

+        getter: getter, operator: operator));

+  }

 }

 

 class SemanticDeclarationTestVisitor extends SemanticTestVisitor {

@@ -5846,7 +7408,6 @@
     if (initializer != null) {

       apply(initializer, arg);

     }

-    return null;

   }

 

   @override

@@ -5858,7 +7419,6 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,

         element: variable, constant: constant.getText()));

-    return null;

   }

 

   @override

@@ -5911,7 +7471,6 @@
     if (initializer != null) {

       apply(initializer, arg);

     }

-    return null;

   }

 

   @override

@@ -5923,7 +7482,6 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_STATIC_CONSTANT_DECL,

         element: field, constant: constant.getText()));

-    return null;

   }

 

   @override

@@ -5938,7 +7496,6 @@
     if (initializer != null) {

       apply(initializer, arg);

     }

-    return null;

   }

 

   @override

@@ -5950,7 +7507,6 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_CONSTANT_DECL,

         element: field, constant: constant.getText()));

-    return null;

   }

 

   @override

@@ -5965,7 +7521,6 @@
     if (initializer != null) {

       apply(initializer, arg);

     }

-    return null;

   }

 

   @override

@@ -5975,7 +7530,6 @@
       arg) {

     visits.add(new Visit(VisitKind.VISIT_ABSTRACT_GETTER_DECL,

         element: getter));

-    return null;

   }

 

   @override

@@ -5987,7 +7541,6 @@
     visits.add(new Visit(VisitKind.VISIT_ABSTRACT_SETTER_DECL,

         element: setter, parameters: parameters));

     applyParameters(parameters, arg);

-    return null;

   }

 

   @override

@@ -5999,7 +7552,6 @@
     visits.add(new Visit(VisitKind.VISIT_INSTANCE_GETTER_DECL,

         element: getter, body: body));

     apply(body, arg);

-    return null;

   }

 

   @override

@@ -6013,7 +7565,6 @@
         element: setter, parameters: parameters, body: body));

     applyParameters(parameters, arg);

     apply(body, arg);

-    return null;

   }

 

   @override

@@ -6025,7 +7576,6 @@
     visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_DECL,

         element: getter, body: body));

     apply(body, arg);

-    return null;

   }

 

   @override

@@ -6039,7 +7589,6 @@
         element: setter, parameters: parameters, body: body));

     applyParameters(parameters, arg);

     apply(body, arg);

-    return null;

   }

 

   @override

@@ -6051,7 +7600,6 @@
     visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_DECL,

         element: getter, body: body));

     apply(body, arg);

-    return null;

   }

 

   @override

@@ -6065,7 +7613,6 @@
         element: setter, parameters: parameters, body: body));

     applyParameters(parameters, arg);

     apply(body, arg);

-    return null;

   }

 

   @override

@@ -6221,6 +7768,10 @@
   VISIT_PARAMETER_COMPOUND,

   VISIT_PARAMETER_PREFIX,

   VISIT_PARAMETER_POSTFIX,

+  VISIT_FINAL_PARAMETER_SET,

+  VISIT_FINAL_PARAMETER_COMPOUND,

+  VISIT_FINAL_PARAMETER_PREFIX,

+  VISIT_FINAL_PARAMETER_POSTFIX,

 

   VISIT_LOCAL_VARIABLE_GET,

   VISIT_LOCAL_VARIABLE_SET,

@@ -6230,11 +7781,19 @@
   VISIT_LOCAL_VARIABLE_POSTFIX,

   VISIT_LOCAL_VARIABLE_DECL,

   VISIT_LOCAL_CONSTANT_DECL,

+  VISIT_FINAL_LOCAL_VARIABLE_SET,

+  VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,

+  VISIT_FINAL_LOCAL_VARIABLE_PREFIX,

+  VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,

 

   VISIT_LOCAL_FUNCTION_GET,

   VISIT_LOCAL_FUNCTION_INVOKE,

   VISIT_LOCAL_FUNCTION_DECL,

   VISIT_CLOSURE_DECL,

+  VISIT_LOCAL_FUNCTION_SET,

+  VISIT_LOCAL_FUNCTION_COMPOUND,

+  VISIT_LOCAL_FUNCTION_PREFIX,

+  VISIT_LOCAL_FUNCTION_POSTFIX,

 

   VISIT_STATIC_FIELD_GET,

   VISIT_STATIC_FIELD_SET,

@@ -6246,32 +7805,63 @@
   VISIT_STATIC_CONSTANT_DECL,

 

   VISIT_STATIC_GETTER_GET,

-  VISIT_STATIC_SETTER_SET,

+  VISIT_STATIC_GETTER_SET,

   VISIT_STATIC_GETTER_INVOKE,

+

+  VISIT_STATIC_SETTER_GET,

+  VISIT_STATIC_SETTER_SET,

+  VISIT_STATIC_SETTER_INVOKE,

+

   VISIT_STATIC_GETTER_SETTER_COMPOUND,

   VISIT_STATIC_METHOD_SETTER_COMPOUND,

   VISIT_STATIC_GETTER_SETTER_PREFIX,

   VISIT_STATIC_GETTER_SETTER_POSTFIX,

+

   VISIT_STATIC_GETTER_DECL,

   VISIT_STATIC_SETTER_DECL,

 

+  VISIT_FINAL_STATIC_FIELD_SET,

+  VISIT_STATIC_FINAL_FIELD_COMPOUND,

+  VISIT_STATIC_FINAL_FIELD_POSTFIX,

+  VISIT_STATIC_FINAL_FIELD_PREFIX,

+

   VISIT_STATIC_FUNCTION_GET,

+  VISIT_STATIC_FUNCTION_SET,

   VISIT_STATIC_FUNCTION_INVOKE,

   VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,

   VISIT_STATIC_FUNCTION_DECL,

+  VISIT_STATIC_METHOD_SETTER_PREFIX,

+  VISIT_STATIC_METHOD_SETTER_POSTFIX,

+

+  VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,

+  VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,

+  VISIT_STATIC_METHOD_COMPOUND,

+  VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,

+  VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,

+  VISIT_STATIC_METHOD_PREFIX,

+  VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,

+  VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,

+  VISIT_STATIC_METHOD_POSTFIX,

 

   VISIT_TOP_LEVEL_FIELD_GET,

   VISIT_TOP_LEVEL_FIELD_SET,

   VISIT_TOP_LEVEL_FIELD_INVOKE,

+  VISIT_FINAL_TOP_LEVEL_FIELD_SET,

   VISIT_TOP_LEVEL_FIELD_COMPOUND,

   VISIT_TOP_LEVEL_FIELD_PREFIX,

   VISIT_TOP_LEVEL_FIELD_POSTFIX,

   VISIT_TOP_LEVEL_FIELD_DECL,

   VISIT_TOP_LEVEL_CONSTANT_DECL,

+  VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,

+  VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,

+  VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,

 

   VISIT_TOP_LEVEL_GETTER_GET,

-  VISIT_TOP_LEVEL_SETTER_SET,

+  VISIT_TOP_LEVEL_GETTER_SET,

   VISIT_TOP_LEVEL_GETTER_INVOKE,

+  VISIT_TOP_LEVEL_SETTER_GET,

+  VISIT_TOP_LEVEL_SETTER_SET,

+  VISIT_TOP_LEVEL_SETTER_INVOKE,

   VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,

   VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,

   VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,

@@ -6279,9 +7869,23 @@
   VISIT_TOP_LEVEL_SETTER_DECL,

 

   VISIT_TOP_LEVEL_FUNCTION_GET,

+  VISIT_TOP_LEVEL_FUNCTION_SET,

   VISIT_TOP_LEVEL_FUNCTION_INVOKE,

   VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,

   VISIT_TOP_LEVEL_FUNCTION_DECL,

+  VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,

+  VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,

+  VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,

+

+  VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,

+  VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,

+  VISIT_TOP_LEVEL_METHOD_COMPOUND,

+  VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,

+  VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,

+  VISIT_TOP_LEVEL_METHOD_PREFIX,

+  VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,

+  VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,

+  VISIT_TOP_LEVEL_METHOD_POSTFIX,

 

   VISIT_DYNAMIC_PROPERTY_GET,

   VISIT_DYNAMIC_PROPERTY_SET,

@@ -6302,14 +7906,24 @@
 

   VISIT_SUPER_FIELD_GET,

   VISIT_SUPER_FIELD_SET,

+  VISIT_FINAL_SUPER_FIELD_SET,

   VISIT_SUPER_FIELD_INVOKE,

   VISIT_SUPER_FIELD_COMPOUND,

   VISIT_SUPER_FIELD_PREFIX,

   VISIT_SUPER_FIELD_POSTFIX,

+  VISIT_SUPER_FINAL_FIELD_COMPOUND,

+  VISIT_SUPER_FINAL_FIELD_PREFIX,

+  VISIT_SUPER_FINAL_FIELD_POSTFIX,

+  VISIT_SUPER_FIELD_FIELD_COMPOUND,

+  VISIT_SUPER_FIELD_FIELD_PREFIX,

+  VISIT_SUPER_FIELD_FIELD_POSTFIX,

 

   VISIT_SUPER_GETTER_GET,

-  VISIT_SUPER_SETTER_SET,

+  VISIT_SUPER_GETTER_SET,

   VISIT_SUPER_GETTER_INVOKE,

+  VISIT_SUPER_SETTER_GET,

+  VISIT_SUPER_SETTER_SET,

+  VISIT_SUPER_SETTER_INVOKE,

   VISIT_SUPER_GETTER_SETTER_COMPOUND,

   VISIT_SUPER_GETTER_FIELD_COMPOUND,

   VISIT_SUPER_FIELD_SETTER_COMPOUND,

@@ -6321,10 +7935,18 @@
   VISIT_SUPER_FIELD_SETTER_POSTFIX,

 

   VISIT_SUPER_METHOD_GET,

+  VISIT_SUPER_METHOD_SET,

   VISIT_SUPER_METHOD_INVOKE,

   VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,

+  VISIT_SUPER_METHOD_SETTER_COMPOUND,

+  VISIT_SUPER_METHOD_SETTER_PREFIX,

+  VISIT_SUPER_METHOD_SETTER_POSTFIX,

+  VISIT_SUPER_METHOD_COMPOUND,

+  VISIT_SUPER_METHOD_PREFIX,

+  VISIT_SUPER_METHOD_POSTFIX,

 

   VISIT_UNRESOLVED_GET,

+  VISIT_UNRESOLVED_SET,

   VISIT_UNRESOLVED_INVOKE,

   VISIT_UNRESOLVED_SUPER_GET,

   VISIT_UNRESOLVED_SUPER_INVOKE,

@@ -6343,12 +7965,24 @@
   VISIT_SUPER_EQUALS,

   VISIT_SUPER_NOT_EQUALS,

   VISIT_SUPER_INDEX_PREFIX,

+  VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,

+  VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,

+  VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,

+  VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,

+  VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,

   VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,

   VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,

   VISIT_SUPER_INDEX_POSTFIX,

+  VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,

+  VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,

+  VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,

   VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,

   VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,

 

+  VISIT_UNRESOLVED_SUPER_COMPOUND,

+  VISIT_UNRESOLVED_SUPER_PREFIX,

+  VISIT_UNRESOLVED_SUPER_POSTFIX,

+

   VISIT_UNARY,

   VISIT_SUPER_UNARY,

   VISIT_UNRESOLVED_SUPER_UNARY,

@@ -6359,40 +7993,37 @@
   VISIT_CLASS_TYPE_LITERAL_GET,

   VISIT_CLASS_TYPE_LITERAL_SET,

   VISIT_CLASS_TYPE_LITERAL_INVOKE,

-  VISIT_CLASS_TYPE_LITERAL_BINARY,

-  ERROR_CLASS_TYPE_LITERAL_COMPOUND,

-  ERROR_CLASS_TYPE_LITERAL_PREFIX,

-  ERROR_CLASS_TYPE_LITERAL_POSTFIX,

+  VISIT_CLASS_TYPE_LITERAL_COMPOUND,

+  VISIT_CLASS_TYPE_LITERAL_PREFIX,

+  VISIT_CLASS_TYPE_LITERAL_POSTFIX,

 

   VISIT_TYPEDEF_TYPE_LITERAL_GET,

   VISIT_TYPEDEF_TYPE_LITERAL_SET,

   VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,

-  VISIT_TYPEDEF_TYPE_LITERAL_BINARY,

-  ERROR_TYPEDEF_TYPE_LITERAL_COMPOUND,

-  ERROR_TYPEDEF_TYPE_LITERAL_PREFIX,

-  ERROR_TYPEDEF_TYPE_LITERAL_POSTFIX,

+  VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,

+  VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,

+  VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,

 

   VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,

   VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,

   VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,

-  VISIT_TYPE_VARIABLE_TYPE_LITERAL_BINARY,

-  ERROR_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

-  ERROR_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,

-  ERROR_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,

+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,

+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,

 

   VISIT_DYNAMIC_TYPE_LITERAL_GET,

   VISIT_DYNAMIC_TYPE_LITERAL_SET,

   VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,

-  VISIT_DYNAMIC_TYPE_LITERAL_BINARY,

-  ERROR_DYNAMIC_TYPE_LITERAL_COMPOUND,

-  ERROR_DYNAMIC_TYPE_LITERAL_PREFIX,

-  ERROR_DYNAMIC_TYPE_LITERAL_POSTFIX,

+  VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,

+  VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,

+  VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,

 

   VISIT_INDEX_SET,

   VISIT_COMPOUND_INDEX_SET,

   VISIT_SUPER_INDEX_SET,

   VISIT_UNRESOLVED_SUPER_INDEX_SET,

   VISIT_SUPER_COMPOUND_INDEX_SET,

+  VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,

   VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,

   VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,

 

@@ -6438,7 +8069,9 @@
   VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,

   VISIT_NAMED_INITIALIZING_FORMAL_DECL,

 

-  ERROR_UNRESOLVED_POSTFIX,

+  VISIT_UNRESOLVED_COMPOUND,

+  VISIT_UNRESOLVED_PREFIX,

+  VISIT_UNRESOLVED_POSTFIX,

 

   // TODO(johnniwinther): Add tests for more error cases.

 }

diff --git a/tests/compiler/dart2js/source_map_name_test.dart b/tests/compiler/dart2js/source_map_name_test.dart
new file mode 100644
index 0000000..110fff5
--- /dev/null
+++ b/tests/compiler/dart2js/source_map_name_test.dart
@@ -0,0 +1,165 @@
+// 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 source_map_name_test;
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/dart2jslib.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/io/source_information.dart';
+import 'memory_compiler.dart';
+
+const String SOURCE = '''
+
+var toplevelField;
+void toplevelMethod() {}
+void toplevelAnonymous() {
+  var foo = () {};
+}
+void toplevelLocal() {
+  void localMethod() {}
+}
+
+class Class {
+  Class() {
+    var foo = () {};
+  }
+  Class.named() {
+    void localMethod() {}
+  }
+  static var staticField;
+  static staticMethod() {}
+  static void staticAnonymous() {
+    var foo = () {};
+  }
+  static void staticLocal() {
+    void localMethod() {}
+  }
+  var instanceField;
+  instanceMethod() {}
+  void instanceAnonymous() {
+    var foo = () {};
+  }
+  void instanceLocal() {
+    void localMethod() {}
+  }
+  void instanceNestedLocal() {
+    void localMethod() {
+      var foo = () {};
+      void nestedLocalMethod() {}
+    }
+  }
+}
+
+main() {
+  toplevelField = toplevelMethod();
+  toplevelAnonymous();
+  toplevelLocal();
+
+  Class.staticField = Class.staticMethod;
+  Class.staticAnonymous();
+  Class.staticLocal();
+
+  var c = new Class();
+  c = new Class.named();
+  c.instanceField = c.instanceMethod();
+  c.instanceAnonymous();
+  c.instanceLocal();
+  c.instanceNestedLocal();
+}
+''';
+
+check(Element element, String expectedName) {
+  String name = computeElementNameForSourceMaps(element);
+  Expect.equals(
+      expectedName,
+      name,
+      "Unexpected name '$name' for $element, expected '$expectedName'.");
+}
+
+main() {
+  asyncTest(() async {
+    Compiler compiler = compilerFor({'main.dart': SOURCE});
+    await compiler.run(Uri.parse('memory:main.dart'));
+
+    Element lookup(String name) {
+      Element element;
+      int dotPosition = name.indexOf('.');
+      if (dotPosition != -1) {
+        String clsName = name.substring(0, dotPosition);
+        ClassElement cls = compiler.mainApp.find(clsName);
+        Expect.isNotNull(cls, "Class '$clsName' not found.");
+        element = cls.localLookup(name.substring(dotPosition + 1));
+      } else {
+        element = compiler.mainApp.find(name);
+      }
+      Expect.isNotNull(element, "Element '$name' not found.");
+      return element;
+    }
+
+    void checkName(String expectedName,
+                   [List<String> expectedClosureNames,
+                    String lookupName]) {
+      if (lookupName == null) {
+        lookupName = expectedName;
+      }
+      var element = lookup(lookupName);
+      check(element, expectedName);
+      if (element.isConstructor) {
+        var constructorBody =
+            element.enclosingClass.lookupBackendMember(element.name);
+        Expect.isNotNull(element,
+                         "Constructor body '${element.name}' not found.");
+        check(constructorBody, expectedName);
+      }
+
+      if (expectedClosureNames != null) {
+        int index = 0;
+        for (var closure in element.nestedClosures) {
+          String expectedName = expectedClosureNames[index];
+          check(closure, expectedName);
+          check(closure.expression, expectedName);
+          check(closure.enclosingClass, expectedName);
+          index++;
+        }
+      }
+    }
+
+    checkName('toplevelField');
+    checkName('toplevelMethod');
+    checkName('toplevelAnonymous',
+              ['toplevelAnonymous.<anonymous function>']);
+    checkName('toplevelLocal',
+              ['toplevelLocal.localMethod']);
+    checkName('Class');
+    checkName('main');
+
+    checkName('Class.staticField');
+    checkName('Class.staticMethod');
+    checkName('Class.staticAnonymous',
+              ['Class.staticAnonymous.<anonymous function>']);
+    checkName('Class.staticLocal',
+              ['Class.staticLocal.localMethod']);
+
+    checkName('Class',
+              ['Class.<anonymous function>'],
+              'Class.');
+    checkName('Class.named',
+              ['Class.named.localMethod']);
+
+    checkName('Class.instanceField');
+    checkName('Class.instanceMethod');
+    checkName('Class.instanceAnonymous',
+              ['Class.instanceAnonymous.<anonymous function>']);
+    checkName('Class.instanceLocal',
+              ['Class.instanceLocal.localMethod']);
+    checkName('Class.instanceNestedLocal',
+              ['Class.instanceNestedLocal.localMethod',
+               'Class.instanceNestedLocal.localMethod.<anonymous function>',
+               'Class.instanceNestedLocal.localMethod.nestedLocalMethod']);
+
+
+  });
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/source_map_validator_helper.dart b/tests/compiler/dart2js/source_map_validator_helper.dart
index e8be063..e8ca28c 100644
--- a/tests/compiler/dart2js/source_map_validator_helper.dart
+++ b/tests/compiler/dart2js/source_map_validator_helper.dart
@@ -11,11 +11,16 @@
 import 'package:source_maps/source_maps.dart' hide SourceFile;
 import 'package:compiler/src/apiimpl.dart';
 import 'package:compiler/src/elements/elements.dart'
-    show LibraryElement,
-         CompilationUnitElement,
+    show AstElement,
          ClassElement,
-         AstElement;
+         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;
 
 validateSourceMap(Uri targetUri,
                   {Uri mainUri,
@@ -143,16 +148,58 @@
                               positionFromOffset(end));
         }
 
+        AstElement findInnermost(AstElement element) {
+          bool isInsideElement(FunctionElement closure) {
+            Element enclosing = closure;
+            while (enclosing != null) {
+              if (enclosing == element) return true;
+              enclosing = enclosing.enclosingElement;
+            }
+            return false;
+          }
+
+          if (element is MemberElement) {
+            MemberElement member = element;
+            member.nestedClosures.forEach((closure) {
+              var localFunction = closure.expression;
+              Interval interval = intervalFromElement(localFunction);
+              if (interval != null &&
+                  interval.contains(sourcePosition) &&
+                  isInsideElement(localFunction)) {
+                element = localFunction;
+              }
+            });
+          }
+          return element;
+        }
+
         void match(AstElement element) {
           Interval interval = intervalFromElement(element);
           if (interval != null && interval.contains(sourcePosition)) {
-            if (name != 'call') {
-              // TODO(johnniwinther): Check closures.
-              Expect.equals(element.name, name);
-            } else if (name != element.name) {
-              print("${targetUri}$targetPosition:\n"
-                    "Name '$name' does not match element $element in "
-                    "${sourceFile.filename}$sourcePosition.");
+            AstElement innerElement = findInnermost(element);
+            String expectedName =
+                computeElementNameForSourceMaps(innerElement);
+            if (name != expectedName) {
+              // For the code
+              //    (){}();
+              //    ^
+              // the indicated position is within the scope of the local
+              // function but it is also the position for the invocation of it.
+              // Allow name to be either from the local or from its calling
+              // context.
+              if (innerElement.isLocal && innerElement.isFunction) {
+                var enclosingElement = innerElement.enclosingElement;
+                String expectedName2 =
+                    computeElementNameForSourceMaps(enclosingElement);
+                Expect.isTrue(name == expectedName2,
+                    "Unexpected name '${name}', "
+                    "expected '${expectedName}' for $innerElement "
+                    "or '${expectedName2}' for $enclosingElement.");
+              } else {
+                Expect.equals(expectedName, name,
+                    "Unexpected name '${name}', "
+                    "expected '${expectedName}' or for $innerElement.");
+              }
             }
           }
         }
@@ -266,7 +313,7 @@
            line == other.line && column <= other.column;
   }
 
-  String toString() => '[$line,$column]';
+  String toString() => '[${line + 1},${column + 1}]';
 }
 
 class Interval {
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 1d717e5..939640d 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -2038,7 +2038,7 @@
     return analyzeTopLevel(code, expectedWarnings);
   }
   return Future.wait([
-    check("Future<int> foo() async { return; }", MessageKind.RETURN_NOTHING),
+    check("Future<int> foo() async { return; }"),
     check("Future<int> foo() async { return null; }"),
     check("Future<int> foo() async { return 0; }"),
     check("Future<int> foo() async { return ''; }", NOT_ASSIGNABLE),
@@ -2053,7 +2053,7 @@
     check("void foo() async { return 0; }", MessageKind.RETURN_VALUE_IN_VOID),
     check("void foo() async { return new Future.value(); }",
           MessageKind.RETURN_VALUE_IN_VOID),
-    check("int foo() async { return; }", MessageKind.RETURN_NOTHING),
+    check("int foo() async { return; }"),
     check("int foo() async { return 0; }", NOT_ASSIGNABLE),
     check("int foo() async { return new Future<int>.value(); }",
           NOT_ASSIGNABLE),
diff --git a/tests/compiler/dart2js/type_equals_test.dart b/tests/compiler/dart2js/type_equals_test.dart
index 2d01b36..16e1066 100644
--- a/tests/compiler/dart2js/type_equals_test.dart
+++ b/tests/compiler/dart2js/type_equals_test.dart
@@ -34,14 +34,14 @@
     type1 = signature1.type.returnType;
   } else {
     // Otherwise use the first argument type.
-    type1 = signature1.requiredParameters.head.computeType(compiler);
+    type1 = signature1.requiredParameters.first.type;
   }
   if (signature2.requiredParameterCount == 0) {
     // If parameters is empty, use return type.
     type2 = signature2.type.returnType;
   } else {
     // Otherwise use the first argument type.
-    type2 = signature2.requiredParameters.head.computeType(compiler);
+    type2 = signature2.requiredParameters.first.type;
   }
   if (expect) {
     Expect.equals(type1, type2, "$type1 != $type2");
diff --git a/tests/compiler/dart2js/type_substitution_test.dart b/tests/compiler/dart2js/type_substitution_test.dart
index b166c1b..17a4b14 100644
--- a/tests/compiler/dart2js/type_substitution_test.dart
+++ b/tests/compiler/dart2js/type_substitution_test.dart
@@ -30,7 +30,7 @@
     return signature.type.returnType;
   } else {
     // Otherwise use the first argument type.
-    return signature.requiredParameters.head.computeType(compiler);
+    return signature.requiredParameters.first.type;
   }
 }
 
diff --git a/tests/compiler/dart2js_extra/23486_helper.dart b/tests/compiler/dart2js_extra/23486_helper.dart
new file mode 100644
index 0000000..c15d826
--- /dev/null
+++ b/tests/compiler/dart2js_extra/23486_helper.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+int x = 1;
diff --git a/tests/compiler/dart2js_extra/23486_test.dart b/tests/compiler/dart2js_extra/23486_test.dart
new file mode 100644
index 0000000..1d8eb39
--- /dev/null
+++ b/tests/compiler/dart2js_extra/23486_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for http://dartbug.com/23486/
+//
+// Dart2js used to crash when using `super` and prefixes inside parenthesized
+// expressions.
+import 'package:expect/expect.dart';
+
+import '23486_helper.dart' as p;
+
+class B {
+  var field = 1;
+}
+
+class A extends B {
+  m() {
+    (super).field = 1; /// 01: compile-time error
+  }
+}
+
+class C {
+  C();
+  C.name();
+}
+
+class D extends C {
+  D() : super();
+  D.name() : (super).name(); /// 02: compile-time error
+}
+
+main() {
+  Expect.throws(new A().m);          /// 01: continued
+  Expect.throws(() => new D.name()); /// 02: continued
+  Expect.throws(() => (p).x);        /// 03: static type warning
+}
+
diff --git a/tests/compiler/dart2js_extra/conditional_send_test.dart b/tests/compiler/dart2js_extra/conditional_send_test.dart
new file mode 100644
index 0000000..c95203d
--- /dev/null
+++ b/tests/compiler/dart2js_extra/conditional_send_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-null-aware-operators
+import "package:expect/expect.dart";
+
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
+
+class A {
+  int x;
+  m() => "a";
+}
+
+main(args) {
+  var a = confuse(true) ? null : new A();
+  a?.x = 3;
+  Expect.throws(() => a.m());
+}
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 7f04ef9..dec2c23 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -65,24 +65,24 @@
 10216a_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 10216b_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 12320_test: Crash #  Unhandled node
-16407_test: Crash # unsupported element kind: foo:field
 17094_test: RuntimeError # Please triage this failure.
-17645_test: Crash # unsupported element kind: log:field
-21166_test: Crash # unsupported element kind: a:field
 21666_test: Crash # Instance of 'TypeOperator': type check unimplemented for fInt.
 22868_test: Crash #  cannot handle async/sync*/async* functions
 22895_test: Crash #  cannot handle async/sync*/async* functions
 22917_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 23264_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+23486_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+23486_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+23486_test/03: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 LayoutTests_fast_mediastream_getusermedia_t01_test/01: Crash # Please triage this failure.
 async_stacktrace_test/asyncStar: Crash #  cannot handle async/sync*/async* functions
 async_stacktrace_test/none: Crash #  cannot handle async/sync*/async* functions
 bailout8_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-bound_closure_interceptor_methods_test: Crash # unsupported element kind: getter2:field
-bound_closure_interceptor_type_test: Crash # unsupported element kind: checkers:field
+bound_closure_interceptor_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for IntToT<String>.
 checked_accessor_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 closure_capture5_test: Crash # (i=0): For-loop variable captured in loop header
 code_motion_exception_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_send_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 constant_javascript_semantics2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 constant_javascript_semantics3_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 deferred/deferred_class_test: Crash # (lib.loadLibrary()): handleStaticGetterInvoke: foreign: getter(loadLibrary)
@@ -97,13 +97,11 @@
 do_test: Timeout # Please triage this failure.
 for_test: Timeout # Please triage this failure.
 generics_factories_test: Crash # Please triage this failure.
-generics_is_check1_test: Crash # Instance of 'TypeOperator': type check unimplemented for Hest<int>.
-hash_code_test: Crash # unsupported element kind: hash:field
+if_null_test: Crash # Please triage this failure.
 inference_nsm_mirrors_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 inferrer_is_int_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 interface_type_optimization_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 is_check_instanceof_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
-mirror_enqueuer_regression_test: Crash # unsupported element kind: foo:field
 mirror_invalid_field_access2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirror_invalid_field_access3_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirror_invalid_field_access4_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -115,24 +113,18 @@
 mirrors_declarations_filtering_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors_used_closure_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors_used_native_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-mirrors_used_warning2_test: Crash # unsupported element kind: lines:field
-mirrors_used_warning_test/minif: Crash # unsupported element kind: lines:field
-mirrors_used_warning_test/none: Crash # unsupported element kind: lines:field
 no_such_method_mirrors_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 reflect_native_types_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 regress/4492_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 regress/4515_1_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 regress/4515_2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 regress/4740_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-runtime_type_test: Crash # Please triage this failure.
 super_constructor1_test: RuntimeError # Please triage this failure.
 switch_test/01: Crash #  Unhandled node
 switch_test/02: Crash #  Unhandled node
 switch_test/none: Crash # (switch (val){}): Unhandled node
 this_phi_elimination_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-type_argument_factory_crash_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
-type_argument_factory_nocrash_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
 type_constant_switch_test/none: Crash # (switch (v){}): Unhandled node
 typevariable_factory_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<T>.
-typevariable_substitution_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<T>.
 while_test: Timeout # Please triage this failure.
+16407_test : Pass
diff --git a/tests/compiler/dart2js_extra/if_null_test.dart b/tests/compiler/dart2js_extra/if_null_test.dart
new file mode 100644
index 0000000..deb9b64
--- /dev/null
+++ b/tests/compiler/dart2js_extra/if_null_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-null-aware-operators
+import "package:expect/expect.dart";
+
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
+
+main(args) {
+  var x = new A();
+  var y;
+
+  // Checks that inference doesn't incorrectly treat this as a normal
+  // assignment (where only B is a possible value after the assignment).
+  var c = x ??= new B();
+  var z = x;
+  Expect.equals('a', x.m());
+  Expect.equals('a', z.m());
+  Expect.equals('a', c.m());
+  if (confuse(true)) y = x;
+  Expect.equals('a', y.m());
+
+  // Similar test, within fields.
+  new C();
+  new D();
+}
+
+class A { m() => 'a'; }
+class B { m() => 'b'; }
+
+class C {
+  var y;
+  C() {
+    y = new A();
+    var c = y ??= new B();
+    Expect.equals('a', y.m());
+    Expect.equals('a', c.m());
+  }
+}
+
+class D {
+  var y;
+  D() {
+    this.y = new A();
+    var c = this.y ??= new B();
+    Expect.equals('a', y.m());
+    Expect.equals('a', c.m());
+  }
+}
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index 964d76f..d078f3b 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -28,7 +28,7 @@
 browser_compat_1_unpatched_test: Crash # unsupported element kind: getTagCallCount:function
 browser_compat_2_test: Crash # unsupported element kind: getTagCallCount:function
 catch_javascript_null_stack_trace_test: Crash # (JS('','(function () {throw null;})()')): handleStaticFunctionInvoke: foreign: function(JS)
-core_type_check_native_test: Crash # unsupported element kind: inscrutable:field
+core_type_check_native_test: Crash # unsupported element kind: makeD:function
 downcast_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 event_loop_test: Crash # unsupported element kind: foo:function
 fake_thing_2_test: Crash # unsupported element kind: make3:function
@@ -126,4 +126,3 @@
 super_call_test: Crash # unsupported element kind: makeD:function
 super_property_test: Crash # unsupported element kind: makeB:function
 undefined_bailout_test: Crash # (JS('','void 0')): handleStaticFunctionInvoke: foreign: function(JS)
-uninstantiated_type_parameter_test: Crash # Instance of 'TypeOperator': type check unimplemented for C<int>.
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index ebd3de4..461f169 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -211,7 +211,6 @@
 
 [ $compiler == dart2js && $cps_ir ]
 apply2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-apply_test: Crash # Please triage this failure.
 bool_from_environment_test: RuntimeError # Please triage this failure.
 collection_removes_test: RuntimeError # Please triage this failure.
 const_list_remove_range_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -219,20 +218,14 @@
 core_runtime_types_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 date_time_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 double_ceil2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-double_ceil_test: RuntimeError # Please triage this failure.
 double_floor2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-double_floor_test: RuntimeError # Please triage this failure.
 double_parse_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 double_parse_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 double_round2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-double_round4_test: RuntimeError # Please triage this failure.
-double_round_test: RuntimeError # Please triage this failure.
 double_truncate2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-double_truncate_test: RuntimeError # Please triage this failure.
 duration2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 duration_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 error_stack_trace1_test: Pass # Please triage this failure.
-error_stack_trace2_test: Crash # unsupported element kind: cyclicStatic:field
 error_stack_trace_test: Crash # (switch (5){case 5:nested();default:Expect.fail("Should not reach");}): Unhandled node
 expando_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 growable_list_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -246,32 +239,27 @@
 int_parse_radix_test/01: Crash # Please triage this failure.
 int_parse_radix_test/02: Crash # Please triage this failure.
 int_parse_radix_test/none: Crash # Please triage this failure.
-is_operator_basic_types_test: RuntimeError # Please triage this failure.
 iterable_element_at_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+iterable_empty_test: Crash # Instance of 'TypeOperator': type check unimplemented for Iterable<int>.
 iterable_expand_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 iterable_first_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 iterable_first_where_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 iterable_fold_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-iterable_generate_test: Crash # Instance of 'TypeOperator': type check unimplemented for Iterable<int>.
 iterable_last_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 iterable_last_where_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-iterable_mapping_test: RuntimeError # Please triage this failure.
 iterable_reduce_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 iterable_return_type_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for Map<int, int>.
 iterable_return_type_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for Map<int, int>.
-iterable_return_type_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for Map<int, int>.
+iterable_return_type_test/none : RuntimeError
 iterable_single_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 iterable_single_where_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 iterable_skip_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 iterable_take_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-iterable_to_list_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
-iterable_to_set_test: Crash # Instance of 'TypeOperator': type check unimplemented for Set<int>.
-json_map_test: Crash # Instance of 'TypeOperator': type check unimplemented for Map<String, dynamic>.
-linked_hash_map_from_iterable_test: Crash # Instance of 'TypeOperator': type check unimplemented for Map<int, String>.
+iterable_to_list_test : RuntimeError
+iterable_to_set_test : RuntimeError
 linked_hash_map_from_iterables_test: Crash # Instance of 'TypeOperator': type check unimplemented for Map<int, String>.
 list_as_map_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 list_fill_range_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-list_filled_type_argument_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
 list_first_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 list_fixed_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 list_for_each_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -291,21 +279,16 @@
 list_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 list_to_string2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 list_to_string_test: RuntimeError # Please triage this failure.
-list_unmodifiable_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<E>.
-map_from_iterable_test: Crash # Instance of 'TypeOperator': type check unimplemented for Map<String, String>.
 map_from_iterables_test: Crash # Instance of 'TypeOperator': type check unimplemented for Map<int, String>.
-map_keys2_test: Crash # Instance of 'TypeOperator': type check unimplemented for Iterable<String>.
 map_test: Crash # Please triage this failure.
 map_to_string_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-map_values2_test: Crash # Instance of 'TypeOperator': type check unimplemented for Iterable<int>.
-map_values3_test: Crash # Instance of 'TypeOperator': type check unimplemented for Iterable<String>.
-map_values4_test: Crash # Instance of 'TypeOperator': type check unimplemented for Iterable<String>.
+map_values2_test : RuntimeError
+map_values3_test : RuntimeError
+map_values4_test : RuntimeError
 null_nosuchmethod_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-null_test: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
 num_clamp_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 num_parse_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 num_parse_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-num_sign_test: Crash # unsupported element kind: numbers:field
 queue_first_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 queue_last_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 queue_single_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -322,7 +305,6 @@
 set_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 set_to_string_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 shuffle_test: RuntimeError # Please triage this failure.
-splay_tree_from_iterable_test: Crash # Instance of 'TypeOperator': type check unimplemented for Map<int, String>.
 splay_tree_from_iterables_test: Crash # Instance of 'TypeOperator': type check unimplemented for Map<int, String>.
 splay_tree_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 string_buffer_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -338,8 +320,7 @@
 string_source_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 string_substring_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 string_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-symbol_operator_test/03: Crash # unsupported element kind: $:field
-symbol_operator_test/none: Crash # unsupported element kind: $:field
+symbol_operator_test/03: RuntimeError # Please triage this failure.
 symbol_reserved_word_test/03: Pass # Please triage this failure.
 symbol_reserved_word_test/06: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 symbol_reserved_word_test/09: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
diff --git a/tests/corelib/iterable_empty_test.dart b/tests/corelib/iterable_empty_test.dart
new file mode 100644
index 0000000..75adfa7
--- /dev/null
+++ b/tests/corelib/iterable_empty_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+  testEmpty(name, it, [depth = 2]) {
+    Expect.isTrue(it.isEmpty, name);
+    Expect.isFalse(it.isNotEmpty, name);
+    Expect.equals(0, it.length, name);
+    Expect.isFalse(it.contains(null), name);
+    Expect.isFalse(it.any((x)=>true), name);
+    Expect.isTrue(it.every((x)=>false), name);
+    Expect.throws(() => it.first, (e) => e is StateError, name);
+    Expect.throws(() => it.last, (e) => e is StateError, name);
+    Expect.throws(() => it.single, (e) => e is StateError, name);
+    Expect.throws(() => it.elementAt(0), (e) => e is RangeError, name);
+    Expect.throws(() => it.reduce((a, b) => a), (e) => e is StateError, name);
+    Expect.throws(() => it.singleWhere((_) => true),
+                  (e) => e is StateError, name);
+    Expect.equals(42, it.fold(42, (a, b) => "not 42"), name);
+    Expect.equals(42, it.firstWhere((v) => true, orElse: () => 42), name);
+    Expect.equals(42, it.lastWhere((v) => true, orElse: () => 42), name);
+    Expect.equals("", it.join("separator"), name);
+    Expect.equals("()", it.toString(), name);
+    Expect.listEquals([], it.toList(), name);
+    Expect.listEquals([], it.toList(growable: false), name);
+    Expect.listEquals([], it.toList(growable: true), name);
+    Expect.equals(0, it.toSet().length, name);
+    // Doesn't throw:
+    it.forEach((v) => throw v);
+    for (var v in it) {
+      throw v;
+    }
+    // Check that returned iterables are also empty.
+    if (depth > 0) {
+      testEmpty("$name-map", it.map((x)=>x), depth - 1);
+      testEmpty("$name-where", it.where((x)=>true), depth - 1);
+      testEmpty("$name-expand", it.expand((x)=>[x]), depth - 1);
+      testEmpty("$name-skip", it.skip(1), depth - 1);
+      testEmpty("$name-take", it.take(2), depth - 1);
+      testEmpty("$name-skipWhile", it.skipWhile((v) => false), depth - 1);
+      testEmpty("$name-takeWhile", it.takeWhile((v) => true), depth - 1);
+    }
+  }
+
+  testType(name, it, [depth = 2]) {
+    Expect.isTrue(it is Iterable<int>, name);
+    Expect.isFalse(it is Iterable<String>, name);
+    if (depth > 0) {
+      testType("$name-where", it.where((_)=>true), depth - 1);
+      testType("$name-skip", it.skip(1), depth - 1);
+      testType("$name-take", it.take(1), depth - 1);
+      testType("$name-skipWhile", it.skipWhile((_)=>false), depth - 1);
+      testType("$name-takeWhile", it.takeWhile((_)=>true), depth - 1);
+      testType("$name-toList", it.toList(), depth - 1);
+      testType("$name-toList", it.toList(growable: false), depth - 1);
+      testType("$name-toList", it.toList(growable: true), depth - 1);
+      testType("$name-toSet", it.toSet(), depth - 1);
+    }
+  }
+
+  test(name, it) {
+    testEmpty(name, it);
+    testType(name, it);
+  }
+
+  test("const", const Iterable<int>.empty());
+  test("new", new Iterable<int>.empty());
+}
+
diff --git a/tests/html/html.status b/tests/html/html.status
index f8e3b2b..38c4a2e 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -102,12 +102,12 @@
 
 [ $runtime == chrome ]
 touchevent_test/supported: Fail # Touch events are only supported on touch devices
-element_animate_test/omit_timing: Skip # Timing out inexplicably. Temporarily suppressing (alanknight)
-element_animate_test/timing_dict: Skip # Timing out inexplicably. Temporarily suppressing (alanknight)
 
-[ $runtime == chrome && ($system == windows || $system == macos) ]
-# New failure on Chrome 42.  Linux bots are not yet updated.
-element_animate_test/simple_timing: RuntimeError # Please triage this failure
+[ $runtime == chrome && $system == macos ]
+element_animate_test/omit_timing: Skip # Timing out on MacOS. Issue 23507
+element_animate_test/timing_dict: Skip # Timing out on MacOS. Issue 23507
+transition_event_test/functional: Skip # Times out. Issue 22167
+request_animation_frame_test: Skip # Times out. Issue 22167
 
 [$runtime == drt || $runtime == dartium || $runtime == chrome || $runtime == chromeOnAndroid || $runtime == ContentShellOnAndroid ]
 webgl_1_test: Pass, Fail # Issue 8219
@@ -138,8 +138,6 @@
 event_test: RuntimeError # Issue 23437. Only three failures, but hard to break them out.
 wheelevent_test: RuntimeError # Issue 23437
 text_event_test: RuntimeError # Issue 23437
-
-[$runtime == ie10 || $runtime == ie11 || ($runtime == chrome && $system == macos)]
 transition_event_test/functional: Skip # Times out. Issue 22167
 request_animation_frame_test: Skip # Times out. Issue 22167
 
@@ -299,7 +297,6 @@
 indexeddb_2_test: RuntimeError # Issue 21433
 indexeddb_4_test: RuntimeError # Issue 21433
 indexeddb_5_test: RuntimeError # Issue 21433
-js_test: RuntimeError # Issue 21434
 
 [ $runtime == opera ]
 blob_constructor_test: Fail
@@ -416,51 +413,50 @@
 window_nosuchmethod_test: StaticWarning
 
 [ $compiler == dart2js && $cps_ir ]
-async_spawnuri_test: Crash # unsupported element kind: _defaultEnvironment:field
-async_test: Crash # unsupported element kind: _defaultEnvironment:field
+async_spawnuri_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+async_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 audiobuffersourcenode_test: Crash #  try/finally
 audiocontext_test: Crash #  try/finally
-audioelement_test: Crash # unsupported element kind: _escapeRegExp:field
-b_element_test: Crash # unsupported element kind: _defaultEnvironment:field
-blob_constructor_test: Crash # unsupported element kind: _escapeRegExp:field
+audioelement_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+b_element_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+blob_constructor_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 cache_test: Crash #  try/finally
-callbacks_test: Crash # unsupported element kind: _defaultEnvironment:field
+callbacks_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 canvas_pixel_array_type_alias_test: Crash #  try/finally
-canvas_test: Crash # unsupported element kind: _escapeRegExp:field
+canvas_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 canvasrenderingcontext2d_test: Crash #  try/finally
-cdata_test: Crash # unsupported element kind: _escapeRegExp:field
-client_rect_test: Crash # unsupported element kind: _escapeRegExp:field
+cdata_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+client_rect_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<Rectangle>.
 cross_domain_iframe_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 crypto_test: Crash #  try/finally
-css_rule_list_test: Crash # unsupported element kind: _escapeRegExp:field
+css_rule_list_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<CssRule>.
 css_test: Crash #  try/finally
-cssstyledeclaration_test: Crash # unsupported element kind: _escapeRegExp:field
+cssstyledeclaration_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 custom/attribute_changed_callback_test: Crash #  try/finally
-custom/constructor_calls_created_synchronously_test: Crash # unsupported element kind: _escapeRegExp:field
-custom/created_callback_test: Crash # unsupported element kind: _escapeRegExp:field
-custom/document_register_basic_test: Crash # unsupported element kind: _escapeRegExp:field
+custom/constructor_calls_created_synchronously_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+custom/created_callback_test: Crash # (try {test();}catch (e){rethrow;}finally {js.context['testExpectsGlobalError']=false;}): try/finally
+custom/document_register_basic_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 custom/document_register_type_extensions_test: Crash #  try/finally
-custom/element_upgrade_test: Crash # unsupported element kind: _escapeRegExp:field
+custom/element_upgrade_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 custom/entered_left_view_test: Crash #  try/finally
-custom/js_custom_test: Crash # unsupported element kind: _escapeRegExp:field
-custom/mirrors_test: Crash # unsupported element kind: _escapeRegExp:field
-custom/regress_194523002_test: Crash # unsupported element kind: _defaultEnvironment:field
+custom/js_custom_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+custom/mirrors_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 custom_element_method_clash_test: Crash #  try/finally
 custom_element_name_clash_test: Crash #  try/finally
 custom_elements_23127_test: Crash #  try/finally
 custom_elements_test: Crash #  try/finally
-custom_tags_test: Crash # unsupported element kind: _escapeRegExp:field
-dart_object_local_storage_test: Crash # unsupported element kind: _escapeRegExp:field
-datalistelement_test: Crash # unsupported element kind: _escapeRegExp:field
+custom_tags_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+dart_object_local_storage_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+datalistelement_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 document_test: Crash #  try/finally
-documentfragment_test: Crash # unsupported element kind: _escapeRegExp:field
-dom_constructors_test: Crash # unsupported element kind: _escapeRegExp:field
-domparser_test: Crash # unsupported element kind: _escapeRegExp:field
+documentfragment_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+dom_constructors_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+domparser_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 element_add_test: Crash #  try/finally
 element_animate_test: Crash #  try/finally
-element_classes_svg_test: Crash # unsupported element kind: _escapeRegExp:field
-element_classes_test: Crash # unsupported element kind: _escapeRegExp:field
-element_constructor_1_test: Crash # unsupported element kind: _escapeRegExp:field
+element_classes_svg_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+element_classes_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+element_constructor_1_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 element_dimensions_test: Crash #  try/finally
 element_offset_test: Crash #  try/finally
 element_test: Crash #  try/finally
@@ -471,92 +467,92 @@
 element_types_constructors5_test: Crash #  try/finally
 element_types_constructors6_test: Crash #  try/finally
 element_types_test: Crash #  try/finally
-event_customevent_test: Crash # unsupported element kind: _escapeRegExp:field
-event_test: Crash # unsupported element kind: _escapeRegExp:field
-events_test: Crash # unsupported element kind: _defaultEnvironment:field
-exceptions_test: Crash # unsupported element kind: _escapeRegExp:field
+event_customevent_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+event_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+events_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+exceptions_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 fileapi_test: Crash #  try/finally
 filereader_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-fontface_loaded_test: Crash # unsupported element kind: _escapeRegExp:field
-fontface_test: Crash # unsupported element kind: _escapeRegExp:field
+fontface_loaded_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+fontface_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 form_data_test: Crash #  try/finally
-form_element_test: Crash # unsupported element kind: _escapeRegExp:field
-geolocation_test: Crash # unsupported element kind: _escapeRegExp:field
-hidden_dom_1_test: Crash # unsupported element kind: _escapeRegExp:field
-hidden_dom_2_test: Crash # unsupported element kind: _escapeRegExp:field
+form_element_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+geolocation_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+hidden_dom_1_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+hidden_dom_2_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 history_test: Crash #  try/finally
-htmlcollection_test: Crash # unsupported element kind: _escapeRegExp:field
-htmlelement_test: Crash # unsupported element kind: _escapeRegExp:field
-htmloptionscollection_test: Crash # unsupported element kind: _escapeRegExp:field
+htmlcollection_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+htmlelement_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+htmloptionscollection_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 indexeddb_1_test: Crash #  try/finally
 indexeddb_2_test: Crash # Please triage this failure.
-indexeddb_3_test: Crash # unsupported element kind: _escapeRegExp:field
-indexeddb_4_test: Crash # unsupported element kind: _escapeRegExp:field
-indexeddb_5_test: Crash # unsupported element kind: _escapeRegExp:field
+indexeddb_3_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+indexeddb_4_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+indexeddb_5_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 input_element_test: Crash #  try/finally
 instance_of_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-isolates_test: Crash # unsupported element kind: _defaultEnvironment:field
+isolates_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 js_interop_1_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 js_test: Crash #  try/finally
-keyboard_event_test: Crash # unsupported element kind: _defaultEnvironment:field
+keyboard_event_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 localstorage_test: Crash # (try {fn();}finally {window.localStorage.clear();}): try/finally
-location_test: Crash # unsupported element kind: _escapeRegExp:field
+location_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 media_stream_test: Crash #  try/finally
 mediasource_test: Crash #  try/finally
-messageevent_test: Crash # unsupported element kind: _escapeRegExp:field
-mouse_event_test: Crash # unsupported element kind: _escapeRegExp:field
+messageevent_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+mouse_event_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 mutationobserver_test: Crash #  try/finally
 native_gc_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-navigator_test: Crash # unsupported element kind: _escapeRegExp:field
+navigator_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 node_test: Crash #  try/finally
 node_validator_important_if_you_suppress_make_the_bug_critical_test: Crash #  try/finally
-non_instantiated_is_test: Crash # unsupported element kind: _escapeRegExp:field
+non_instantiated_is_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 notification_test: Crash #  try/finally
 performance_api_test: Crash #  try/finally
 postmessage_structured_test: Crash #  try/finally
-query_test: Crash # unsupported element kind: _escapeRegExp:field
-queryall_test: Crash # unsupported element kind: _escapeRegExp:field
+query_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+queryall_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 range_test: Crash #  try/finally
 request_animation_frame_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 rtc_test: Crash #  try/finally
-selectelement_test: Crash # unsupported element kind: _escapeRegExp:field
-serialized_script_value_test: Crash # unsupported element kind: _escapeRegExp:field
+selectelement_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+serialized_script_value_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 shadow_dom_test: Crash #  try/finally
-shadowroot_test: Crash # unsupported element kind: _escapeRegExp:field
+shadowroot_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 speechrecognition_test: Crash #  try/finally
-storage_quota_test/missingenumcheck: Crash # unsupported element kind: _escapeRegExp:field
-storage_quota_test/none: Crash # unsupported element kind: _escapeRegExp:field
-storage_test: Crash # unsupported element kind: _escapeRegExp:field
-streams_test: Crash # unsupported element kind: _escapeRegExp:field
+storage_quota_test/missingenumcheck: Crash # Instance of 'TypeOperator': type casts not implemented.
+storage_quota_test/none: Crash # Instance of 'TypeOperator': type casts not implemented.
+storage_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+streams_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 svg_test: Crash #  try/finally
 svgelement_test: Crash #  try/finally
-table_test: Crash # unsupported element kind: _escapeRegExp:field
-text_event_test: Crash # unsupported element kind: _escapeRegExp:field
+table_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+text_event_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 touchevent_test: Crash #  try/finally
-track_element_constructor_test: Crash # unsupported element kind: _defaultEnvironment:field
-transferables_test: Crash # unsupported element kind: _escapeRegExp:field
+track_element_constructor_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+transferables_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 transition_event_test: Crash #  try/finally
 typed_arrays_1_test: Crash #  try/finally
-typed_arrays_2_test: Crash # unsupported element kind: _escapeRegExp:field
-typed_arrays_3_test: Crash # unsupported element kind: _escapeRegExp:field
-typed_arrays_4_test: Crash # unsupported element kind: _escapeRegExp:field
-typed_arrays_5_test: Crash # unsupported element kind: _escapeRegExp:field
-typed_arrays_arraybuffer_test: Crash # unsupported element kind: _escapeRegExp:field
-typed_arrays_dataview_test: Crash # unsupported element kind: _escapeRegExp:field
-typed_arrays_range_checks_test: Crash # unsupported element kind: _escapeRegExp:field
-typed_arrays_simd_test: Crash # unsupported element kind: _escapeRegExp:field
-typing_test: Crash # unsupported element kind: _escapeRegExp:field
-unknownelement_test: Crash # unsupported element kind: _escapeRegExp:field
-uri_test: Crash # unsupported element kind: _escapeRegExp:field
+typed_arrays_2_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+typed_arrays_3_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+typed_arrays_4_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+typed_arrays_5_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+typed_arrays_arraybuffer_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+typed_arrays_dataview_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+typed_arrays_range_checks_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+typed_arrays_simd_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+typing_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<StyleSheet>.
+unknownelement_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+uri_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 url_test: Crash #  try/finally
 webgl_1_test: Crash #  try/finally
 websocket_test: Crash #  try/finally
 websql_test: Crash #  try/finally
 wheelevent_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-window_eq_test: Crash # unsupported element kind: _escapeRegExp:field
-window_mangling_test: Crash # unsupported element kind: _escapeRegExp:field
-window_nosuchmethod_test: Crash # unsupported element kind: _escapeRegExp:field
-window_test: Crash # unsupported element kind: _escapeRegExp:field
+window_eq_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+window_mangling_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+window_nosuchmethod_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+window_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 worker_api_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 worker_test: Crash #  try/finally
 xhr_cross_origin_test: Crash #  try/finally
diff --git a/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart b/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
index 4a5fe71..a2a23c6 100644
--- a/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
+++ b/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
@@ -154,7 +154,12 @@
       expect(fragment.childNodes.length, 1);
       expect(fragment.childNodes[0].id, "bad");
       expect(fragment.childNodes[0].childNodes.length, 0);
-    });    
+    });
+
+    testHtml("sanitizes embed",
+      validator,
+      "<div><embed src='' type='application/x-shockwave-flash'></embed></div>",
+      "<div></div>");
   });
 
   group('URI_sanitization', () {
@@ -524,14 +529,33 @@
     "<input id='bad' onmouseover='alert(1)'>",
     "");
 
-    testHtml('tagName makes containing form invalid',
-    validator,
-    "<form onmouseover='alert(2)'><input name='tagName'>",
-    "");
+    test('tagName makes containing form invalid', () {
+      var fragment = document.body.createFragment(
+          "<form onmouseover='alert(2)'><input name='tagName'>",
+          validator: validator);
+      var form = fragment.lastChild;
+      // If the tagName was clobbered, the sanitizer should have removed
+      // the whole thing and form is null.
+      // If the tagName was not clobbered, then there will be content,
+      // but the tagName should be the normal value. IE11 has started
+      // doing this.
+      if (form != null) {
+        expect(form.tagName, 'FORM');
+      }
+    });
 
-    testHtml('tagName without mouseover',
-    validator,
-    "<form><input name='tagName'>",
-    "");
+    test('tagName without mouseover', () {
+      var fragment = document.body.createFragment(
+          "<form><input name='tagName'>",
+          validator: validator);
+      var form = fragment.lastChild;
+      // If the tagName was clobbered, the sanitizer should have removed
+      // the whole thing and form is null.
+      // If the tagName was not clobbered, then there will be content,
+      // but the tagName should be the normal value.
+      if (form != null) {
+        expect(form.tagName, 'FORM');
+      }
+    });
   });
 }
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 9faca85..420d6a4 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -126,7 +126,7 @@
 bool_from_environment_default_value_test: RuntimeError # Please triage this failure.
 count_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 cross_isolate_message_test: Crash #  Unhandled node
-deferred_in_isolate2_test: Crash # unsupported element kind: _defaultEnvironment:field
+deferred_in_isolate2_test: Crash # (lib.loadLibrary()): handleStaticGetterInvoke: foreign: getter(loadLibrary)
 function_send_test: Crash # (try {p.send(func);}finally {p.send(0);}): try/finally
 handle_error2_test: Crash #  Unhandled node
 handle_error3_test: Crash #  Unhandled node
@@ -136,7 +136,7 @@
 int_from_environment_default_value_test: RuntimeError # Please triage this failure.
 isolate_complex_messages_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 isolate_current_test: Crash #  Unhandled node
-mandel_isolate_test: Crash # unsupported element kind: _defaultEnvironment:field
+mandel_isolate_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 message2_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 message3_test/byteBuffer: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 message3_test/constInstance: Crash # Please triage this failure.
@@ -149,15 +149,15 @@
 message_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 mint_maker_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 nested_spawn2_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-nested_spawn_test: Crash # unsupported element kind: _defaultEnvironment:field
+nested_spawn_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 raw_port_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 request_reply_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-spawn_function_custom_class_test: Crash # unsupported element kind: _defaultEnvironment:field
+spawn_function_custom_class_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 spawn_function_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-spawn_uri_multi_test/01: Crash # unsupported element kind: _defaultEnvironment:field
-spawn_uri_multi_test/none: Crash # unsupported element kind: _defaultEnvironment:field
+spawn_uri_multi_test/01: Crash # Instance of 'TypeOperator': type casts not implemented.
+spawn_uri_multi_test/none: Crash # Instance of 'TypeOperator': type casts not implemented.
 stacktrace_message_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 static_function_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 string_from_environment_default_value_test: RuntimeError # Please triage this failure.
-timer_isolate_test: Crash # unsupported element kind: _defaultEnvironment:field
-unresolved_ports_test: Crash # unsupported element kind: _defaultEnvironment:field
+timer_isolate_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+unresolved_ports_test: Crash # Instance of 'TypeOperator': type casts not implemented.
diff --git a/tests/language/conditional_access_helper.dart b/tests/language/conditional_access_helper.dart
index 3b31e28..108857a 100644
--- a/tests/language/conditional_access_helper.dart
+++ b/tests/language/conditional_access_helper.dart
@@ -11,6 +11,9 @@
 
 var topLevelVar;
 
+void topLevelFunction() {}
+
 class C {
   static var staticField;
+  static void staticMethod() {}
 }
diff --git a/tests/language/conditional_method_invocation_test.dart b/tests/language/conditional_method_invocation_test.dart
index e194ab9..4bd6f1f 100644
--- a/tests/language/conditional_method_invocation_test.dart
+++ b/tests/language/conditional_method_invocation_test.dart
@@ -20,6 +20,7 @@
 class C extends B {
   f(callback()) => callback();
   int g(int callback()) => callback();
+  static void staticMethod() {}
 }
 
 C nullC() => null;
diff --git a/tests/language/final_super_field_set_test.dart b/tests/language/final_super_field_set_test.dart
new file mode 100644
index 0000000..9c3289b
--- /dev/null
+++ b/tests/language/final_super_field_set_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class SuperClass {
+  final field = 0;
+  noSuchMethod(_) => 42;
+}
+
+class Class extends SuperClass {
+  m() {
+    super.field = 87; /// 01: static type warning
+  }
+}
+
+main() {
+  new Class().m(); /// 01: continued
+}
\ No newline at end of file
diff --git a/tests/language/language.status b/tests/language/language.status
index bc11d57..c85375e 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -27,8 +27,11 @@
 conditional_property_assignment_test: Fail
 conditional_property_access_test: Fail
 conditional_method_invocation_test: Fail
+this_conditional_operator_test/none: Fail
 
 deferred_redirecting_factory_test: Fail # Issue 23408
+redirecting_constructor_initializer_test: RuntimeError # Issue 23488
+
 [ $compiler == none ]
 # Non-contractive types are not supported in the vm.
 cyclic_type_test/02: Fail, OK
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index a49eff2..eb24cf8 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -28,6 +28,7 @@
 external_test/25: Fail
 constructor_duplicate_final_test/03: Fail
 reify_typevar_static_test/00: MissingCompileTimeError # Issue 21565
+conditional_method_invocation_test/11: MissingStaticWarning # Issue 23461
 
 # Please add new failing tests before this line.
 # Section below is for invalid tests.
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 44878916..5cd9387 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -59,17 +59,8 @@
 regress_22976_test/01: CompileTimeError # Issue 23132
 regress_22976_test/02: CompileTimeError # Issue 23132
 
-# Null-aware operators aren't implemented in dart2js yet.
-if_null_evaluation_order_test: CompileTimeError
-if_null_precedence_test: CompileTimeError
-if_null_behavior_test: CompileTimeError
-if_null_assignment_behavior_test: CompileTimeError
-if_null_assignment_static_test: CompileTimeError
-conditional_property_assignment_test: CompileTimeError
-conditional_property_access_test: CompileTimeError
-conditional_method_invocation_test: CompileTimeError
-super_conditional_operator_test/none: CompileTimeError
-
+if_null_assignment_behavior_test/13: Crash # Issue 23491
+if_null_assignment_behavior_test/14: Crash # Issue 23491
 
 # VM specific tests that should not be run by dart2js.
 vm/*: Skip # Issue 12699
@@ -228,10 +219,7 @@
 
 [ $compiler == dart2js && $cps_ir ]
 aborting_switch_case_test: Crash # (switch (42){case 42:foo();foo();break;}): Unhandled node
-abstract_exact_selector_test/01: Crash # unsupported element kind: a:field
-abstract_exact_selector_test/none: Crash # unsupported element kind: a:field
 abstract_getter_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-abstract_object_method_test: Crash # unsupported element kind: a:field
 abstract_runtime_error_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 abstract_runtime_error_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 arithmetic_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -349,7 +337,7 @@
 await_backwards_compatibility_test/none: Crash # (test1()async{var x=await 9;Expect.equals(9,x);}): cannot handle async/sync*/async* functions
 await_exceptions_test: Crash # (awaitFoo()async{await foo();}): cannot handle async/sync*/async* functions
 await_for_cancel_test: Crash # (test()async{await test1();await test2();}): cannot handle async/sync*/async* functions
-await_for_test: Crash # unsupported element kind: t4:field
+await_for_test: Crash #  cannot handle async/sync*/async* functions
 await_for_use_local_test: Crash #  cannot handle async/sync*/async* functions
 await_future_test: Crash #  cannot handle async/sync*/async* functions
 await_nonfuture_test: Crash # (foo()async{Expect.equals(X,10);return await 5;}): cannot handle async/sync*/async* functions
@@ -357,9 +345,6 @@
 await_postfix_expr_test: Crash #  cannot handle async/sync*/async* functions
 await_regression_test: Crash #  cannot handle async/sync*/async* functions
 await_test: Crash #  cannot handle async/sync*/async* functions
-bailout4_test: Crash # unsupported element kind: a:field
-bailout_container_type_test: Crash # unsupported element kind: a:field
-bailout_test: Crash # unsupported element kind: reachedAfoo:field
 bool_check_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 call_closurization_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 call_nonexistent_static_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -433,14 +418,61 @@
 closure_in_constructor_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
 closure_internals_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 closure_self_reference_test: Crash # (try {return inner(value-1);}finally {counter++ ;}): try/finally
-closure_side_effect_test: Crash # unsupported element kind: c:field
 closure_type_variables_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<int>.
 closures_initializer2_test: Crash # Please triage this failure.
 closures_initializer_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
 compile_time_constant_a_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 compile_time_constant_b_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_method_invocation_test/01: RuntimeError # Please triage this failure.
+conditional_method_invocation_test/02: RuntimeError # Please triage this failure.
+conditional_method_invocation_test/03: RuntimeError # Please triage this failure.
+conditional_method_invocation_test/04: RuntimeError # Please triage this failure.
+conditional_method_invocation_test/05: RuntimeError # Please triage this failure.
+conditional_method_invocation_test/06: RuntimeError # Please triage this failure.
+conditional_method_invocation_test/07: RuntimeError # Please triage this failure.
+conditional_method_invocation_test/08: RuntimeError # Please triage this failure.
+conditional_method_invocation_test/09: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_method_invocation_test/10: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_method_invocation_test/11: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_method_invocation_test/12: RuntimeError # Please triage this failure.
+conditional_method_invocation_test/13: RuntimeError # Please triage this failure.
+conditional_method_invocation_test/none: RuntimeError # Please triage this failure.
+conditional_property_access_test/01: RuntimeError # Please triage this failure.
+conditional_property_access_test/02: RuntimeError # Please triage this failure.
+conditional_property_access_test/03: RuntimeError # Please triage this failure.
+conditional_property_access_test/04: RuntimeError # Please triage this failure.
+conditional_property_access_test/05: RuntimeError # Please triage this failure.
+conditional_property_access_test/06: RuntimeError # Please triage this failure.
+conditional_property_access_test/07: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_access_test/08: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_access_test/09: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_access_test/10: RuntimeError # Please triage this failure.
+conditional_property_access_test/11: RuntimeError # Please triage this failure.
+conditional_property_access_test/none: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/01: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/02: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/03: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/04: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/05: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/06: Crash # Instance of 'TypeOperator': type casts not implemented.
+conditional_property_assignment_test/07: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/08: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/09: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/10: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/11: Crash # Instance of 'TypeOperator': type casts not implemented.
+conditional_property_assignment_test/12: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/13: RuntimeError # Please triage this failure.
+conditional_property_assignment_test/14: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_assignment_test/15: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_assignment_test/16: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_assignment_test/17: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_assignment_test/18: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_assignment_test/19: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_assignment_test/20: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_assignment_test/21: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_assignment_test/22: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+conditional_property_assignment_test/none: RuntimeError # Please triage this failure.
 const_evaluation_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-const_evaluation_test/none: RuntimeError # Please triage this failure.
 const_nested_test: Crash # Please triage this failure.
 const_objects_are_immutable_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 const_objects_are_immutable_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -449,27 +481,19 @@
 const_switch_test/02: Crash #  Unhandled node
 const_switch_test/03: Crash #  Unhandled node
 const_switch_test/04: Crash #  Unhandled node
-constant_propagation_phis_test: RuntimeError # Please triage this failure.
 constructor10_test/01: Crash # Please triage this failure.
 constructor10_test/02: Crash # Please triage this failure.
 constructor11_test: Crash # Please triage this failure.
-constructor12_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<int>.
+constructor12_test: RuntimeError
 constructor3_negative_test: Crash # Please triage this failure.
 constructor5_test: Crash # Please triage this failure.
 constructor_call_wrong_argument_count_negative_test: Crash # Please triage this failure.
 constructor_initializer_test/01: Crash # Please triage this failure.
 constructor_with_mixin_test: Crash # Please triage this failure.
 continue_test: Crash # (switch (0){case 0:i=22;continue;default:i=25;break;}): Unhandled node
-core_type_check_test: RuntimeError # Please triage this failure.
 crash_12118_test: Crash # Please triage this failure.
 crash_6725_test/01: Crash # Please triage this failure.
 custom_await_stack_trace_test: Crash #  cannot handle async/sync*/async* functions
-cyclic_type2_test: Crash # Instance of 'TypeOperator': type check unimplemented for Derived1<Derived1, Derived2>.
-cyclic_type_test/00: RuntimeError # Please triage this failure.
-cyclic_type_test/01: RuntimeError # Please triage this failure.
-cyclic_type_test/02: RuntimeError # Please triage this failure.
-cyclic_type_test/03: RuntimeError # Please triage this failure.
-cyclic_type_test/04: RuntimeError # Please triage this failure.
 deferred_call_empty_before_load_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 deferred_closurize_load_library_test: RuntimeError # Please triage this failure.
 deferred_constant_list_test: Crash # (lib.loadLibrary()): handleStaticGetterInvoke: foreign: getter(loadLibrary)
@@ -526,9 +550,7 @@
 deferred_shared_and_unshared_classes_test: Crash # (lib1.loadLibrary()): handleStaticGetterInvoke: foreign: getter(loadLibrary)
 deferred_static_seperate_test: Crash # (lib1.loadLibrary()): handleStaticGetterInvoke: foreign: getter(loadLibrary)
 deopt_inlined_function_lazy_test: Crash # (try {return x+12342353257893275483274832;}finally {}): try/finally
-deopt_inlined_function_test: Crash # unsupported element kind: obj:field
 div_with_power_of_two2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-div_with_power_of_two_test: Crash # unsupported element kind: expectedResults:field
 double_to_string_as_exponential2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 double_to_string_as_fixed2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 double_to_string_as_precision2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -539,8 +561,6 @@
 enum_private_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 enum_test: Crash #  Unhandled node
 equality_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-error_stacktrace_test: RuntimeError # Please triage this failure.
-evaluation_redirecting_constructor_test: RuntimeError # Please triage this failure.
 execute_finally10_test: Crash #  try/finally
 execute_finally11_test: Crash #  try/finally
 execute_finally12_test: Crash # (try {try {}finally {a=8;break;}}finally {return a==8;}): try/finally
@@ -553,36 +573,17 @@
 execute_finally7_test: Crash #  try/finally
 execute_finally8_test: Crash # (try {sum+= 1;return 'hi';}finally {sum+= 1;throw 'ball';sum+= 1;}): try/finally
 execute_finally9_test: Crash #  try/finally
-f_bounded_equality_test: RuntimeError # Please triage this failure.
 factory3_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
 factory_redirection3_cyclic_test/01: Crash # Please triage this failure.
 factory_redirection_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/03: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
 factory_redirection_test/04: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/05: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/06: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/07: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/08: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/09: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/10: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/11: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/12: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/13: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/14: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
-factory_redirection_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
+factory_redirection_test/05: MissingRuntimeError
+factory_redirection_test/06: MissingRuntimeError
 factory_return_type_checked_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 factory_type_parameter2_test: Crash # Please triage this failure.
 factory_type_parameter_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<List>.
 fast_method_extraction_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
-field_inference_test: Crash # unsupported element kind: array:field
-final_is_not_const_test/none: RuntimeError # Please triage this failure.
-final_syntax_test/03: Crash # unsupported element kind: P3:field
-final_syntax_test/04: Crash # unsupported element kind: P3:field
-final_syntax_test/08: Crash # unsupported element kind: A3:field
-final_syntax_test/09: Crash # unsupported element kind: P3:field
-final_syntax_test/10: Crash # unsupported element kind: B3:field
-final_syntax_test/none: Crash # unsupported element kind: P3:field
+final_super_field_set_test/01: RuntimeError # Please triage this failure.
 finally_test: Crash # (try {i=12;}finally {Expect.equals(12,i);executedFinally=true;}): try/finally
 first_class_types_literals_test/03: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 first_class_types_literals_test/04: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -600,9 +601,6 @@
 fixed_type_variable2_test/04: Crash # Instance of 'TypeOperator': type check unimplemented for T.
 fixed_type_variable2_test/05: Crash # Instance of 'TypeOperator': type check unimplemented for T.
 fixed_type_variable2_test/06: Crash # Instance of 'TypeOperator': type check unimplemented for T.
-fixed_type_variable_test/02: RuntimeError # Please triage this failure.
-fixed_type_variable_test/04: RuntimeError # Please triage this failure.
-fixed_type_variable_test/06: RuntimeError # Please triage this failure.
 flatten_test/01: Crash # (test()async{int x=await new Derived<int>();}): cannot handle async/sync*/async* functions
 flatten_test/02: Crash # (test()async{Future<int> f()async=>new Derived<int>();}): cannot handle async/sync*/async* functions
 flatten_test/03: Crash #  cannot handle async/sync*/async* functions
@@ -617,10 +615,7 @@
 flatten_test/12: Crash #  cannot handle async/sync*/async* functions
 flatten_test/none: Crash # (test()async{}): cannot handle async/sync*/async* functions
 for2_test: Crash # Please triage this failure.
-for_in2_test: Crash # unsupported element kind: set:field
-for_in_side_effects_test: Crash # unsupported element kind: array:field
 for_variable_capture_test: Crash # (i=0): For-loop variable captured in loop header
-forwarding_factory_constructor_default_values_test: RuntimeError # Please triage this failure.
 function_propagation_test: Crash # Instance of 'TypeOperator': type check unimplemented for F.
 function_subtype0_test: Crash # Instance of 'TypeOperator': type check unimplemented for t__.
 function_subtype1_test: Crash # Please triage this failure.
@@ -676,7 +671,6 @@
 function_type_alias3_test: Crash # Instance of 'TypeOperator': type check unimplemented for F.
 function_type_alias4_test: Crash # Instance of 'TypeOperator': type check unimplemented for F.
 function_type_alias6_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for F.
-function_type_alias8_test: Crash # unsupported element kind: fromThing:field
 function_type_alias_test: Crash # Instance of 'TypeOperator': type check unimplemented for Fun.
 function_type_call_getter_test: Crash # Instance of 'TypeOperator': type check unimplemented for F.
 generic2_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
@@ -684,23 +678,116 @@
 generic_constructor_mixin2_test: Crash # Please triage this failure.
 generic_constructor_mixin3_test: Crash # Please triage this failure.
 generic_constructor_mixin_test: Crash # Please triage this failure.
-generic_creation_test: RuntimeError # Please triage this failure.
-generic_deep_test: Crash # Instance of 'TypeOperator': type check unimplemented for S<Z>.
 generic_field_mixin2_test: Crash # Please triage this failure.
 generic_field_mixin3_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<T>.
 generic_field_mixin_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<int>.
-generic_inheritance_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<Object>.
 generic_instanceof2_test: Crash # Instance of 'TypeOperator': type check unimplemented for Foo<int, num>.
-generic_instanceof3_test: Crash # Instance of 'TypeOperator': type check unimplemented for I<String>.
 generic_instanceof4_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
 generic_instanceof5_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
 generic_instanceof_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<T>.
-generic_is_check_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<int>.
 generic_list_checked_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 generic_native_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
 generic_object_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
-generic_parameterized_extends_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<Object>.
 generic_test: Crash # Instance of 'TypeOperator': type check unimplemented for B<AA>.
+if_null_assignment_behavior_test/01: Crash # Please triage this failure.
+if_null_assignment_behavior_test/02: Crash # Please triage this failure.
+if_null_assignment_behavior_test/03: Crash # Please triage this failure.
+if_null_assignment_behavior_test/04: Crash # Please triage this failure.
+if_null_assignment_behavior_test/05: Crash # Please triage this failure.
+if_null_assignment_behavior_test/06: Crash # Please triage this failure.
+if_null_assignment_behavior_test/07: Crash # Please triage this failure.
+if_null_assignment_behavior_test/08: Crash # Please triage this failure.
+if_null_assignment_behavior_test/09: Crash # Please triage this failure.
+if_null_assignment_behavior_test/10: Crash # Please triage this failure.
+if_null_assignment_behavior_test/11: Crash # Please triage this failure.
+if_null_assignment_behavior_test/12: Crash # Please triage this failure.
+if_null_assignment_behavior_test/15: Crash # Please triage this failure.
+if_null_assignment_behavior_test/16: Crash # Please triage this failure.
+if_null_assignment_behavior_test/17: Crash # Please triage this failure.
+if_null_assignment_behavior_test/18: Crash # Please triage this failure.
+if_null_assignment_behavior_test/19: Crash # Please triage this failure.
+if_null_assignment_behavior_test/20: Crash # Please triage this failure.
+if_null_assignment_behavior_test/21: Crash # Please triage this failure.
+if_null_assignment_behavior_test/22: Crash # Please triage this failure.
+if_null_assignment_behavior_test/23: Crash # Please triage this failure.
+if_null_assignment_behavior_test/24: Crash # Please triage this failure.
+if_null_assignment_behavior_test/25: Crash # Please triage this failure.
+if_null_assignment_behavior_test/26: Crash # Please triage this failure.
+if_null_assignment_behavior_test/27: Crash # Please triage this failure.
+if_null_assignment_behavior_test/28: Crash # Please triage this failure.
+if_null_assignment_behavior_test/none: Crash # Please triage this failure.
+if_null_assignment_static_test/01: Crash # Please triage this failure.
+if_null_assignment_static_test/02: Crash # Please triage this failure.
+if_null_assignment_static_test/03: Crash # Please triage this failure.
+if_null_assignment_static_test/04: Crash # Please triage this failure.
+if_null_assignment_static_test/05: Crash # Please triage this failure.
+if_null_assignment_static_test/06: Crash # Please triage this failure.
+if_null_assignment_static_test/07: Crash # Please triage this failure.
+if_null_assignment_static_test/08: Crash # Please triage this failure.
+if_null_assignment_static_test/09: Crash # Please triage this failure.
+if_null_assignment_static_test/10: Crash # Please triage this failure.
+if_null_assignment_static_test/11: Crash # Please triage this failure.
+if_null_assignment_static_test/12: Crash # Please triage this failure.
+if_null_assignment_static_test/13: Crash # Please triage this failure.
+if_null_assignment_static_test/14: Crash # Please triage this failure.
+if_null_assignment_static_test/15: Crash # Please triage this failure.
+if_null_assignment_static_test/16: Crash # Please triage this failure.
+if_null_assignment_static_test/17: Crash # Please triage this failure.
+if_null_assignment_static_test/18: Crash # Please triage this failure.
+if_null_assignment_static_test/19: Crash # Please triage this failure.
+if_null_assignment_static_test/20: Crash # Please triage this failure.
+if_null_assignment_static_test/21: Crash # Please triage this failure.
+if_null_assignment_static_test/22: Crash # Please triage this failure.
+if_null_assignment_static_test/23: Crash # Please triage this failure.
+if_null_assignment_static_test/24: Crash # Please triage this failure.
+if_null_assignment_static_test/25: Crash # Please triage this failure.
+if_null_assignment_static_test/26: Crash # Please triage this failure.
+if_null_assignment_static_test/27: Crash # Please triage this failure.
+if_null_assignment_static_test/28: Crash # Please triage this failure.
+if_null_assignment_static_test/29: Crash # Please triage this failure.
+if_null_assignment_static_test/30: Crash # Please triage this failure.
+if_null_assignment_static_test/31: Crash # Please triage this failure.
+if_null_assignment_static_test/32: Crash # Please triage this failure.
+if_null_assignment_static_test/33: Crash # Please triage this failure.
+if_null_assignment_static_test/34: Crash # Please triage this failure.
+if_null_assignment_static_test/35: Crash # Please triage this failure.
+if_null_assignment_static_test/36: Crash # Please triage this failure.
+if_null_assignment_static_test/37: Crash # Please triage this failure.
+if_null_assignment_static_test/38: Crash # Please triage this failure.
+if_null_assignment_static_test/39: Crash # Please triage this failure.
+if_null_assignment_static_test/40: Crash # Please triage this failure.
+if_null_assignment_static_test/41: Crash # Please triage this failure.
+if_null_assignment_static_test/42: Crash # Please triage this failure.
+if_null_assignment_static_test/none: Crash # Please triage this failure.
+if_null_behavior_test/01: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/02: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/03: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/04: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/05: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/06: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/07: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/08: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/09: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/10: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/11: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/12: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/13: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/14: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/15: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/16: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_behavior_test/none: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_evaluation_order_test/01: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_evaluation_order_test/02: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_evaluation_order_test/none: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_precedence_test/01: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_precedence_test/02: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_precedence_test/03: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_precedence_test/04: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_precedence_test/05: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_precedence_test/06: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_precedence_test/07: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_precedence_test/08: Crash # (null??null): If-null not yet implemented in cps_ir
+if_null_precedence_test/none: Crash # (null??null): If-null not yet implemented in cps_ir
 implicit_super_constructor_call_test: Crash # Please triage this failure.
 import_self_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 inference_captured_variable2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -708,7 +795,6 @@
 inference_list_or_null_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 inference_mixin_field_test: Crash # Please triage this failure.
 inference_super_constructor_call_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-inferrer_closure_test: Crash # unsupported element kind: closure:field
 inferrer_constructor2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 inferrer_constructor3_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 inferrer_constructor4_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -718,18 +804,13 @@
 inferrer_synthesized_super_constructor_test: Crash # Please triage this failure.
 inferrer_this_access_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 infinite_switch_label_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-inline_super_test: Crash # Please triage this failure.
 inlined_throw_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 instance_creation_in_function_annotation_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-instanceof2_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<Object>.
 instanceof3_test: Crash # Instance of 'TypeOperator': type check unimplemented for UndeclaredType.
 instanceof4_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for List<T>.
 instanceof4_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for List<T>.
 integer_division_by_zero_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 interceptor6_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-interceptor7_test: Crash # unsupported element kind: array:field
-interceptor8_test: Crash # unsupported element kind: a:field
-interceptor9_test: RuntimeError # Please triage this failure.
 interceptor_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 internal_library_test/01: Crash # (JS('int','0')): handleStaticFunctionInvoke: foreign: function(JS)
 invocation_mirror_invoke_on2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -743,69 +824,46 @@
 is_malformed_type_test/99: Crash # Instance of 'TypeOperator': type check unimplemented for Undefined.
 is_nan_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 is_not_class2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-is_object_test: RuntimeError # Please triage this failure.
 isnot_malformed_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 issue10581_test: Crash #  Unhandled node
+issue10721_test: RuntimeError
 issue10747_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 issue10783_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 issue11724_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-issue11793_test: Crash # unsupported element kind: otherArray:field
 issue12023_test: Crash #  Unhandled node
 issue12284_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 issue12336_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 issue13474_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-issue13673_test: Crash # unsupported element kind: topLevel:field
 issue14014_3_test: Crash # Please triage this failure.
 issue20476_test: Crash # (try {try {return 1;}catch (e1){}finally {return 3;}}catch (e2){}finally {return 5;}): try/finally
 issue7525_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-issue9687_test: Crash # unsupported element kind: array:field
-issue9939_test: Crash # unsupported element kind: globalVar:field
 issue_1751477_test: Crash # (lib1.loadLibrary()): handleStaticGetterInvoke: foreign: getter(loadLibrary)
 label_test: Crash # (switch (i){case 111:while(doAgain()){break L;}default:i-- ;}): Unhandled node
 large_class_declaration_test: Crash # Please triage this failure.
-large_implicit_getter_test: Crash # unsupported element kind: panels:field
-lazy_map_test: Crash # unsupported element kind: data:field
-lazy_static2_test: Crash # unsupported element kind: x:field
 lazy_static3_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-lazy_static4_test: Crash # unsupported element kind: v:field
-lazy_static5_test: Crash # unsupported element kind: x:field
-lazy_static6_test: Crash # unsupported element kind: x:field
-lazy_static_test: Crash # unsupported element kind: t2:field
 library_ambiguous_test/04: Crash # Instance of 'TypeOperator': type check unimplemented for bax.
 licm2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 licm3_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 list_double_index_in_loop2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 list_double_index_in_loop_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-list_is_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
 list_length_tracer_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 list_literal3_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 list_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<A>.
-list_tracer_in_map_test: Crash # unsupported element kind: b:field
-list_tracer_return_from_tearoff_closure_test: Crash # unsupported element kind: a:field
-logical_expression_test: Crash # unsupported element kind: globalList:field
 malbounded_type_cast2_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 malbounded_type_cast_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 malbounded_type_test2_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<T>.
-malbounded_type_test_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for Super<int>.
-malbounded_type_test_test/04: Crash # Instance of 'TypeOperator': type check unimplemented for Super<String>.
 malformed2_test/00: Crash # Instance of 'TypeOperator': type check unimplemented for List<Unresolved>.
-malformed_inheritance_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for A<String>.
 malformed_inheritance_test/03: Crash # Please triage this failure.
-malformed_inheritance_test/04: Crash # Instance of 'TypeOperator': type check unimplemented for A<String>.
-malformed_inheritance_test/06: Crash # Instance of 'TypeOperator': type check unimplemented for A<String>.
 malformed_inheritance_test/09: Crash # Please triage this failure.
 malformed_inheritance_test/10: Crash # Please triage this failure.
 malformed_test/06: Crash # Please triage this failure.
 malformed_test/none: Crash # Please triage this failure.
-malformed_type_test: Crash # unsupported element kind: x:field
 many_generic_instanceof_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<T>.
 many_overridden_no_such_method_test: RuntimeError # Please triage this failure.
 megamorphic_no_such_method_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 method_override4_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 method_override5_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 method_override_test: Crash # Instance of 'TypeOperator': type check unimplemented for RemoveFunctionType<String, String>.
-methods_as_constants_test: RuntimeError # Please triage this failure.
-minify_closure_variable_collision_test: Crash # unsupported element kind: array:field
 mint_arithmetic_test: Crash #  try/finally
 mixin_bound_test: Crash # Please triage this failure.
 mixin_cyclic_test/01: Crash # Please triage this failure.
@@ -814,7 +872,6 @@
 mixin_field_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mixin_forwarding_constructor1_test: Crash # Please triage this failure.
 mixin_forwarding_constructor3_test: Crash # Please triage this failure.
-mixin_generic_test: Crash # Instance of 'TypeOperator': type check unimplemented for S<Map<int, bool>>.
 mixin_illegal_constructor_test/13: MissingRuntimeError # Please triage this failure.
 mixin_illegal_constructor_test/15: MissingRuntimeError # Please triage this failure.
 mixin_illegal_cycles_test/02: Crash # Please triage this failure.
@@ -830,12 +887,6 @@
 mixin_lib_extends_field_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mixin_lib_extends_method_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mixin_method_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-mixin_mixin4_test: Crash # Instance of 'TypeOperator': type check unimplemented for I<List<bool>>.
-mixin_mixin5_test: Crash # Instance of 'TypeOperator': type check unimplemented for K<int>.
-mixin_mixin6_test: Crash # Instance of 'TypeOperator': type check unimplemented for K<int>.
-mixin_mixin7_test: Crash # Instance of 'TypeOperator': type check unimplemented for K<int>.
-mixin_mixin_bound2_test: Crash # Instance of 'TypeOperator': type check unimplemented for K<int>.
-mixin_mixin_bound_test: Crash # Instance of 'TypeOperator': type check unimplemented for I<List<bool>>.
 mixin_only_for_rti_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
 mixin_super_constructor2_test: Crash # Please triage this failure.
 mixin_super_constructor_default_test: Crash # Please triage this failure.
@@ -845,10 +896,8 @@
 mixin_super_constructor_positionals_test/01: Crash # Please triage this failure.
 mixin_super_constructor_positionals_test/none: Crash # Please triage this failure.
 mixin_super_constructor_test: Crash # Please triage this failure.
-mixin_type_parameter1_test: Crash # Instance of 'TypeOperator': type check unimplemented for Mixin1<num>.
 mixin_type_parameter2_test: Crash # Instance of 'TypeOperator': type check unimplemented for Mixin1<num>.
 mixin_type_parameter3_test: Crash # Instance of 'TypeOperator': type check unimplemented for Mixin1<num>.
-mixin_type_parameter4_test: Crash # Instance of 'TypeOperator': type check unimplemented for R<bool, int>.
 mixin_type_parameters_mixin_extends_test: Crash # Instance of 'TypeOperator': type check unimplemented for M<int>.
 mixin_type_parameters_mixin_test: Crash # Instance of 'TypeOperator': type check unimplemented for M<int>.
 mixin_type_parameters_super_extends_test: Crash # Instance of 'TypeOperator': type check unimplemented for S<int>.
@@ -856,25 +905,22 @@
 mixin_typedef_constructor_test: Crash # Please triage this failure.
 mixin_with_two_implicit_constructors_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 modulo_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-multiple_field_assignment_constructor_test: Crash # unsupported element kind: a:field
+multiple_field_assignment_constructor_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 named_parameter_clash_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 named_parameters_aggregated_test/05: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-namer2_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<String>.
 naming_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 nested_switch_label_test: Crash #  Unhandled node
 no_such_constructor2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 no_such_constructor_test/01: MissingRuntimeError # Please triage this failure.
 no_such_method_dispatcher_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-no_such_method_empty_selector_test: Crash # unsupported element kind: b:field
+no_such_method_empty_selector_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 no_such_method_test: RuntimeError # Please triage this failure.
 non_const_super_negative_test: Crash # Please triage this failure.
 not_enough_positional_arguments_test/00: MissingRuntimeError # Please triage this failure.
 not_enough_positional_arguments_test/03: Crash # Please triage this failure.
-null2_test: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
 null_inline_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 null_is2_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
-null_is_test: RuntimeError # Please triage this failure.
-null_no_such_method_test: Crash # unsupported element kind: array:field
+null_no_such_method_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 null_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
 null_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
 null_test/03: Crash # Instance of 'TypeOperator': type check unimplemented for dynamic.
@@ -886,7 +932,6 @@
 on_catch_malformed_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 operator4_test: RuntimeError # Please triage this failure.
 operator_equals_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-optimize_redundant_array_load_test: Crash # unsupported element kind: A:field
 optimized_constant_array_string_access_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 optimized_string_charat_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 optimized_string_charcodeat_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -902,9 +947,7 @@
 private_access_test/06: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 private_mixin2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 range_analysis2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-redirecting_factory_default_values_test/none: RuntimeError # Please triage this failure.
 redirecting_factory_incompatible_signature_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-redirecting_factory_long_test: Crash # Instance of 'TypeOperator': type check unimplemented for X<int>.
 ref_before_declaration_test/00: Crash # (switch (x){case 0:var x='Does fuzzy logic tickle?';}): Unhandled node
 ref_before_declaration_test/01: Crash # (switch (x){case 0:var x='Does fuzzy logic tickle?';}): Unhandled node
 ref_before_declaration_test/02: Crash # (switch (x){case 0:var x='Does fuzzy logic tickle?';}): Unhandled node
@@ -916,12 +959,9 @@
 ref_before_declaration_test/none: Crash # (switch (x){case 0:var x='Does fuzzy logic tickle?';}): Unhandled node
 refine_receiver_null_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 reg_exp_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-regress_11010_test: Crash # unsupported element kind: caller:field
 regress_12561_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-regress_14105_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<int>.
 regress_18435_test: Crash # Please triage this failure.
 regress_18535_test: Crash # Instance of 'TypeOperator': type check unimplemented for V.
-regress_21016_test: Crash # unsupported element kind: list:field
 regress_21795_test: Crash # (try {foo(t);}finally {if(t==0){try {}catch (err,st){}}}): try/finally
 regress_22438_test: Crash #  cannot handle async/sync*/async* functions
 regress_22443_test: Crash # (D.loadLibrary()): handleStaticGetterInvoke: foreign: getter(loadLibrary)
@@ -933,15 +973,14 @@
 regress_22822_test: Crash # (try {for(int i=0;i<10;i++ ){return ()=>i+b;}}finally {b=10;}): try/finally
 regress_22936_test/01: Crash # Please triage this failure.
 regress_22936_test/none: Crash # Please triage this failure.
-regress_r24720_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<int>.
+regress_23498_test: Crash #  cannot handle async/sync*/async* functions
 reify_typevar_static_test/01: Crash # Please triage this failure.
 return_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 side_effect_throw_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-smaller_4_Interface_Types_A11_t02_test: Crash # Instance of 'TypeOperator': type check unimplemented for G<C, C, C>.
-smi_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for Comparable<double>.
 stack_trace_test: Crash #  try/finally
 statement_test: Crash #  try/finally
 static_postfix_operator_test: Crash # (try {if(a++ ==0){inIt=true;}}finally {}): try/finally
+static_setter_get_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 string_charcode_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 string_optimizations_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 super_all_named_constructor_test: Crash # Please triage this failure.
@@ -953,14 +992,13 @@
 super_inferrer_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 super_operator_index2_test: RuntimeError # Please triage this failure.
 super_operator_index5_test: Crash # (super[0]=42): visitUnresolvedSuperIndexSet
-super_operator_index6_test: Crash # (super[0]+=1): visitUnresolvedSuperGetterCompoundIndexSet
 super_operator_index7_test: Crash # (super[0]=42): visitUnresolvedSuperIndexSet
 super_operator_index8_test: Crash # (super[f()]=g()): visitUnresolvedSuperIndexSet
-super_operator_index_test/01: Crash # (super[4]+=5): visitUnresolvedSuperGetterCompoundIndexSet
+super_operator_index_test/01: Crash # Please triage this failure.
 super_operator_index_test/03: Crash # (super[4]=42): visitUnresolvedSuperIndexSet
-super_operator_index_test/04: Crash # (super[4]+=5): visitUnresolvedSuperSetterCompoundIndexSet
+super_operator_index_test/04: Crash # Please triage this failure.
 super_operator_index_test/05: Crash # (super[4]=42): visitUnresolvedSuperIndexSet
-super_operator_index_test/06: Crash # (super[4]+=5): visitUnresolvedSuperGetterCompoundIndexSet
+super_operator_index_test/06: Crash # Please triage this failure.
 super_operator_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 switch6_test: Crash # (switch (a){case 0:{x=0;break;}case 1:x=1;break;}): Unhandled node
 switch8_test: Crash # (switch (new List(1)[0]){case const A():throw 'Test failed';}): Unhandled node
@@ -1009,27 +1047,19 @@
 throw8_test: Crash #  try/finally
 throw_expr_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 throw_test: Crash #  try/finally
-throwing_lazy_variable_test: Crash # unsupported element kind: a:field
 truncdiv_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-truncdiv_uint32_test: Crash # unsupported element kind: a:field
 try_catch3_test: Crash #  try/finally
 try_catch4_test: Crash #  try/finally
 try_catch5_test: Crash # (try {try {a=8;return;}finally {b=8==a;entered=true;continue;}}finally {continue;}): try/finally
 try_catch_on_syntax_test/07: Crash # Instance of 'TypeOperator': type check unimplemented for UndefinedClass.
-try_catch_optimized1_test: RuntimeError # Please triage this failure.
 try_catch_optimized2_test: Crash # (try {bar();}finally {}): try/finally
-try_catch_optimized3_test: RuntimeError # Please triage this failure.
-try_catch_optimized4_test: Crash # unsupported element kind: a:field
 try_catch_osr_test: Crash # (try {if(x==null)throw 42;return 99;}finally {}): try/finally
 try_catch_syntax_test/08: Crash # Instance of 'TypeOperator': type check unimplemented for MammaMia.
 try_catch_test/01: Crash # Please triage this failure.
 try_catch_test/none: Crash # Please triage this failure.
 type_argument_in_super_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-type_argument_substitution_test: Crash # Instance of 'TypeOperator': type check unimplemented for X<A<String>>.
 type_check_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-type_conversion_ssa_test: Crash # unsupported element kind: array:field
 type_error_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-type_guard_conversion_test: RuntimeError # Please triage this failure.
 type_literal_prefix_call_test/00: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 type_parameter_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for Set<int>.
 type_parameter_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for Set<int>.
@@ -1038,23 +1068,6 @@
 type_parameter_test/05: Crash # Instance of 'TypeOperator': type check unimplemented for Set<int>.
 type_parameter_test/06: Crash # Instance of 'TypeOperator': type check unimplemented for Set<int>.
 type_parameter_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for Set<int>.
-type_promotion_closure_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/03: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/04: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/05: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/06: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/07: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/08: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/09: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/10: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/11: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/12: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/13: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/14: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/15: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/16: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
-type_promotion_closure_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for List<B>.
 type_promotion_functions_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for FuncDynToDyn.
 type_promotion_functions_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for FuncDynToDyn.
 type_promotion_functions_test/03: Crash # Instance of 'TypeOperator': type check unimplemented for FuncDynToDyn.
@@ -1070,23 +1083,8 @@
 type_promotion_functions_test/13: Crash # Instance of 'TypeOperator': type check unimplemented for FuncDynToDyn.
 type_promotion_functions_test/14: Crash # Instance of 'TypeOperator': type check unimplemented for FuncDynToDyn.
 type_promotion_functions_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for FuncDynToDyn.
-type_promotion_more_specific_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/03: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/04: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/05: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/06: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/07: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/08: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/09: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/10: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/11: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/12: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/13: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
-type_promotion_more_specific_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for E<A>.
 type_propagation_in_for_update_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-type_variable_bounds3_test/00: Crash # Instance of 'TypeOperator': type check unimplemented for A<X>.
-type_variable_closure2_test: Crash # Instance of 'TypeOperator': type check unimplemented for A<int>.
+type_variable_closure2_test: RuntimeError
 type_variable_closure_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 type_variable_conflict2_test/03: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 type_variable_conflict2_test/04: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -1097,7 +1095,6 @@
 type_variable_field_initializer_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
 type_variable_function_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for Func<S>.
 type_variable_initializer_test: Crash # Instance of 'TypeOperator': type check unimplemented for Map<int, int>.
-type_variable_nested_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
 type_variable_typedef_test: Crash # Please triage this failure.
 typed_equality_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 typedef_is_test: Crash # Instance of 'TypeOperator': type check unimplemented for Func1.
@@ -1105,8 +1102,6 @@
 typevariable_substitution2_test/02: Crash # Please triage this failure.
 typevariable_substitution2_test/none: Crash # Please triage this failure.
 unresolved_default_constructor_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-unresolved_top_level_method_negative_test: Crash # unsupported element kind: a:field
-unresolved_top_level_var_negative_test: Crash # unsupported element kind: a:field
 value_range2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 value_range3_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 value_range_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
diff --git a/tests/language/redirecting_constructor_initializer_test.dart b/tests/language/redirecting_constructor_initializer_test.dart
new file mode 100644
index 0000000..97c8005
--- /dev/null
+++ b/tests/language/redirecting_constructor_initializer_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+var string = '';
+
+append(x) {
+  string += x;
+  return x;
+}
+
+class A {
+  var x = append('x');
+  var y;
+  var z;
+
+  // Should append y but not yet x.
+  A() : this.foo(append('y'));
+
+  // Append x and z.
+  A.foo(this.y) : z = append('z');
+}
+
+class B extends A {
+  var w;
+
+  // Call the redirecting constructor using super.
+  B() : super(), w = append('w');
+}
+
+main() {
+  string = '';
+  new A();
+  Expect.equals('yxz', string);
+
+  string = '';
+  new B();
+  Expect.equals('yxzw', string);
+}
diff --git a/tests/language/regress_23498_test.dart b/tests/language/regress_23498_test.dart
new file mode 100644
index 0000000..ba7a140
--- /dev/null
+++ b/tests/language/regress_23498_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "package:expect/expect.dart";
+
+foo() async {
+  try {
+    try {
+      await new Future.error('error');
+    } catch (error) {
+      print("caught once");
+      throw 'error';
+    }
+  } catch (error) {
+    print("caught twice");
+    throw 'error';
+  }
+}
+
+main() async {
+  var error = "no error";
+  try {
+    await foo();
+  } catch (e) {
+    error = e;
+  }
+  Expect.equals("error", error);
+}
+
diff --git a/tests/language/static_getter_no_setter1_test.dart b/tests/language/static_getter_no_setter1_test.dart
new file mode 100644
index 0000000..431bbdc
--- /dev/null
+++ b/tests/language/static_getter_no_setter1_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+bool getter_visited = false;
+
+class Class {
+  static int get getter {
+    getter_visited = true;
+  }
+
+  method() {
+    try {
+      getter++; /// 01: static type warning
+    } on NoSuchMethodError catch(e) {
+      Expect.isTrue(getter_visited); /// 01: continued
+      return;
+    }
+    Expect.fail('Expected NoSuchMethodError'); /// 01: continued
+  }
+}
+
+main() {
+  new Class().method();
+}
\ No newline at end of file
diff --git a/tests/language/static_getter_no_setter2_test.dart b/tests/language/static_getter_no_setter2_test.dart
new file mode 100644
index 0000000..508f175
--- /dev/null
+++ b/tests/language/static_getter_no_setter2_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class Class {
+  static int get getter => 0;
+
+  method() {
+    try {
+      getter++; /// 01: static type warning
+    } on NoSuchMethodError catch(e) {
+      return;
+    }
+    Expect.fail('Expected NoSuchMethodError'); /// 01: continued
+  }
+
+  noSuchMethod(i) {
+    return 42;
+  }
+}
+
+class Subclass extends Class {
+  method() {
+    print(getter); /// 01: continued
+    super.method();
+  }
+}
+
+main() {
+  new Subclass().method();
+}
\ No newline at end of file
diff --git a/tests/language/static_getter_no_setter3_test.dart b/tests/language/static_getter_no_setter3_test.dart
new file mode 100644
index 0000000..c466e7d
--- /dev/null
+++ b/tests/language/static_getter_no_setter3_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+bool getter_visited = false;
+
+class Class {
+  static final int getter = (){
+    getter_visited = true;
+  }();
+
+  method() {
+    try {
+      getter++; /// 01: static type warning
+    } on NoSuchMethodError catch(e) {
+      Expect.isTrue(getter_visited); /// 01: continued
+      return;
+    }
+    Expect.fail('Expected NoSuchMethodError'); /// 01: continued
+  }
+}
+
+main() {
+  new Class().method();
+}
\ No newline at end of file
diff --git a/tests/language/static_setter_get_test.dart b/tests/language/static_setter_get_test.dart
new file mode 100644
index 0000000..a10c1d9
--- /dev/null
+++ b/tests/language/static_setter_get_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class Class {
+  static set o(_) {}
+  m() => o; /// 01: static type warning
+  noSuchMethod(_) => 42;
+}
+
+main() {
+  Expect.throws(() => new Class().m()); /// 01: continued
+}
\ No newline at end of file
diff --git a/tests/language/this_conditional_operator_test.dart b/tests/language/this_conditional_operator_test.dart
new file mode 100644
index 0000000..0a88c49
--- /dev/null
+++ b/tests/language/this_conditional_operator_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verify that the ?. operator cannot be used for forwarding "this"
+// constructors.
+
+// SharedOptions=--enable-null-aware-operators
+
+class B {
+  B();
+  B.namedConstructor();
+  var field = 1;
+  method() => 1;
+
+  B.forward()
+    : this?.namedConstructor() /// 01: compile-time error
+  ;
+
+  test() {
+    this?.field = 1;
+    this?.field += 1;
+    this?.field;
+    this?.method();
+  }
+}
+
+main() {
+  new B.forward().test();
+}
diff --git a/tests/language/top_level_getter_no_setter1_test.dart b/tests/language/top_level_getter_no_setter1_test.dart
new file mode 100644
index 0000000..80b429e
--- /dev/null
+++ b/tests/language/top_level_getter_no_setter1_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+bool getter_visited = false;
+
+int get getter {
+  getter_visited = true;
+}
+
+class Class {
+  method() {
+    try {
+      getter++; /// 01: static type warning
+    } on NoSuchMethodError catch(e) {
+      Expect.isTrue(getter_visited); /// 01: continued
+      return;
+    }
+    Expect.fail('Expected NoSuchMethodError'); /// 01: continued
+  }
+}
+
+main() {
+  new Class().method();
+}
\ No newline at end of file
diff --git a/tests/language/top_level_getter_no_setter2_test.dart b/tests/language/top_level_getter_no_setter2_test.dart
new file mode 100644
index 0000000..98c437e
--- /dev/null
+++ b/tests/language/top_level_getter_no_setter2_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+bool getter_visited = false;
+
+final int getter = (){
+  getter_visited = true;
+}();
+
+class Class {
+
+  method() {
+    try {
+      getter++; /// 01: static type warning
+    } on NoSuchMethodError catch(e) {
+      Expect.isTrue(getter_visited); /// 01: continued
+      return;
+    }
+    Expect.fail('Expected NoSuchMethodError'); /// 01: continued
+  }
+}
+
+main() {
+  new Class().method();
+}
\ No newline at end of file
diff --git a/tests/lib/convert/json_toEncodable_reviver_test.dart b/tests/lib/convert/json_toEncodable_reviver_test.dart
index 5843887..77ff1d4 100644
--- a/tests/lib/convert/json_toEncodable_reviver_test.dart
+++ b/tests/lib/convert/json_toEncodable_reviver_test.dart
@@ -38,4 +38,18 @@
   var a = extendedJson.decode(extendedJson.encode(new A(499)));
   Expect.isTrue(a is A);
   Expect.equals(499, a.x);
+
+  testInvalidMap();
+}
+
+
+void testInvalidMap() {
+  var map = {"a" : 42, "b": 42, 37: 42};  // Non-string key.
+  var enc = new JsonEncoder((_) => "fixed");
+  var res = enc.convert(map);
+  Expect.equals('"fixed"', res);
+
+  enc = new JsonEncoder.withIndent(" ", (_) => "fixed");
+  res = enc.convert(map);
+  Expect.equals('"fixed"', res);
 }
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 5ff1e3c..e68b833 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -19,6 +19,7 @@
 mirrors/constructor_kinds_test: RuntimeError # Issue 13799
 mirrors/constructor_private_name_test: CompileTimeError # Issue 13597
 mirrors/deferred_type_test: RuntimeError # Issue 6335
+mirrors/empty_test: RuntimeError # Issue 6490
 mirrors/enum_test: RuntimeError # Issue 6490
 mirrors/fake_function_with_call_test: RuntimeError # Issue 11612
 mirrors/fake_function_without_call_test: RuntimeError # Issue 11612
@@ -282,6 +283,8 @@
 
 mirrors/deferred_mirrors_metadata_test: Fail # Issue 17522
 
+developer/metrics_test: Fail # Issue 20309
+developer/metrics_num_test: Fail # Issue 20309
 profiler/metrics_test: Fail # Issue 20309
 profiler/metrics_num_test: Fail # Issue 20309
 
@@ -297,6 +300,9 @@
 [ $compiler == dart2js && $mode == debug ]
 mirrors/native_class_test: Pass, Slow
 
+[ $compiler == none && $arch == mips ]
+async/timer_regress22626_test: Pass, RuntimeError # Issue 22626
+
 [ $arch == simarm || $arch == simarmv5te ]
 convert/chunked_conversion_utf88_test: Skip  # Pass, Slow Issue 12644.
 convert/utf85_test: Skip  # Pass, Slow Issue 12644.
@@ -305,7 +311,7 @@
 mirrors/mirrors_reader_test: Pass, Slow
 
 [ $compiler == dart2js ]
-profiler/metrics_num_test: Skip # Because of a int / double type test.
+developer/metrics_num_test: Skip # Because of a int / double type test.
 
 [ $arch == simarm64 ]
 convert/utf85_test: Skip # Pass, Slow Issue 20111.
@@ -324,36 +330,30 @@
 async/first_regression_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/future_timeout_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/future_value_chain4_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-async/intercept_print1_test: Crash # unsupported element kind: events:field
-async/intercept_schedule_microtask2_test: Crash # unsupported element kind: events:field
-async/intercept_schedule_microtask3_test: Crash # unsupported element kind: events:field
-async/intercept_schedule_microtask4_test: Crash # unsupported element kind: events:field
-async/intercept_schedule_microtask5_test: Crash # unsupported element kind: events:field
-async/intercept_schedule_microtask6_test: Crash # unsupported element kind: events:field
 async/multiple_timer_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/schedule_microtask2_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/schedule_microtask3_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/schedule_microtask5_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/schedule_microtask_test: Crash # Please triage this failure.
-async/stream_controller_async_test: Crash # unsupported element kind: _defaultEnvironment:field
+async/stream_controller_async_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_controller_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-async/stream_first_where_test: Crash # unsupported element kind: _defaultEnvironment:field
-async/stream_from_iterable_test: Crash # unsupported element kind: _defaultEnvironment:field
+async/stream_first_where_test: Crash # Instance of 'TypeOperator': type casts not implemented.
+async/stream_from_iterable_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_iterator_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_join_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-async/stream_last_where_test: Crash # unsupported element kind: _defaultEnvironment:field
+async/stream_last_where_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_listen_zone_test: Crash #  Unhandled node
 async/stream_periodic2_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_periodic3_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-async/stream_periodic4_test: Crash # unsupported element kind: _defaultEnvironment:field
+async/stream_periodic4_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_periodic5_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_periodic_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-async/stream_single_test: Crash # unsupported element kind: _defaultEnvironment:field
+async/stream_single_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_single_to_multi_subscriber_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_state_nonzero_timer_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_state_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_subscription_as_future_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-async/stream_subscription_cancel_test: Crash # unsupported element kind: _escapeRegExp:field
+async/stream_subscription_cancel_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_timeout_test: Crash # Please triage this failure.
 async/stream_transform_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/stream_transformation_broadcast_test: Crash # Instance of 'TypeOperator': type casts not implemented.
@@ -361,45 +361,28 @@
 async/timer_cancel2_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/timer_cancel_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/timer_isActive_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-async/timer_regress22626_test: Crash # unsupported element kind: rng:field
 async/timer_repeat_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 async/timer_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-async/zone_debug_test: Crash # unsupported element kind: events:field
-async/zone_error_callback_test: Crash # unsupported element kind: replaceZoneSpec:field
 collection/linked_list_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 convert/ascii_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 convert/chunked_conversion2_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_json_decode1_test: Crash # unsupported element kind: TESTS:field
-convert/chunked_conversion_json_encode1_test: Crash # unsupported element kind: TESTS:field
 convert/chunked_conversion_utf82_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-convert/chunked_conversion_utf84_test: Crash # unsupported element kind: UNICODE_TESTS:field
-convert/chunked_conversion_utf85_test: Crash # unsupported element kind: UNICODE_TESTS:field
 convert/chunked_conversion_utf86_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 convert/chunked_conversion_utf87_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-convert/chunked_conversion_utf8_test: Crash # unsupported element kind: UNICODE_TESTS:field
-convert/encoding_test: Crash # unsupported element kind: UNICODE_TESTS:field
 convert/json_chunk_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-convert/json_lib_test: Crash # unsupported element kind: _escapeRegExp:field
+convert/json_lib_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
 convert/json_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-convert/json_toEncodable_reviver_test: RuntimeError # Please triage this failure.
-convert/json_utf8_chunk_test: Crash # unsupported element kind: UNICODE_TESTS:field
+convert/json_utf8_chunk_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 convert/json_util_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 convert/latin1_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 convert/line_splitter_test: Crash # Please triage this failure.
-convert/streamed_conversion_json_decode1_test: Crash # unsupported element kind: TESTS:field
-convert/streamed_conversion_json_encode1_test: Crash # unsupported element kind: TESTS:field
-convert/streamed_conversion_json_utf8_decode_test: Crash # unsupported element kind: JSON_UTF8:field
-convert/streamed_conversion_json_utf8_encode_test: Crash # unsupported element kind: JSON_UTF8:field
-convert/streamed_conversion_utf8_decode_test: Crash # unsupported element kind: UNICODE_TESTS:field
-convert/streamed_conversion_utf8_encode_test: Crash # unsupported element kind: UNICODE_TESTS:field
 convert/utf82_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 convert/utf8_encode_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 convert/utf8_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-js/null_test: Crash # unsupported element kind: _escapeRegExp:field
-math/double_pow_test: Crash # unsupported element kind: samples:field
+js/null_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 math/math_parse_double_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 math/min_max_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-math/point_test: Crash # unsupported element kind: _escapeRegExp:field
+math/point_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 math/random_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 math/rectangle_test: Crash # Please triage this failure.
 mirrors/abstract_class_test/00: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -484,11 +467,6 @@
 mirrors/intercepted_class_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/intercepted_object_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/intercepted_superclass_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-mirrors/invocation_fuzz_test/emptyarray: Crash # unsupported element kind: queue:field
-mirrors/invocation_fuzz_test/false: Crash # unsupported element kind: queue:field
-mirrors/invocation_fuzz_test/none: Crash # unsupported element kind: queue:field
-mirrors/invocation_fuzz_test/smi: Crash # unsupported element kind: queue:field
-mirrors/invocation_fuzz_test/string: Crash # unsupported element kind: queue:field
 mirrors/invoke_call_on_closure_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/invoke_call_through_getter_previously_accessed_test/named: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/invoke_call_through_getter_previously_accessed_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -508,7 +486,7 @@
 mirrors/invoke_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/invoke_throws_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/is_odd_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-mirrors/lazy_static_test: Crash # unsupported element kind: hello:field
+mirrors/lazy_static_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/libraries_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/library_declarations_test/01: Crash # (=Superclass.inheritedNormalFactory;): Unhandled node
 mirrors/library_declarations_test/none: Crash # (=Superclass.inheritedNormalFactory;): Unhandled node
@@ -524,7 +502,7 @@
 mirrors/library_imports_prefixed_show_hide_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/library_imports_prefixed_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/library_imports_shown_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-mirrors/library_uri_package_test: Crash # unsupported element kind: _escapeRegExp:field
+mirrors/library_uri_package_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 mirrors/list_constructor_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/list_constructor_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/load_library_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -560,24 +538,22 @@
 mirrors/metadata_constructor_arguments_test/06: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/metadata_constructor_arguments_test/07: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/metadata_constructor_arguments_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-mirrors/metadata_nested_constructor_call_test/01: Crash # unsupported element kind: closure:field
-mirrors/metadata_nested_constructor_call_test/02: Crash # unsupported element kind: closure:field
-mirrors/metadata_nested_constructor_call_test/03: Crash # unsupported element kind: closure:field
-mirrors/metadata_nested_constructor_call_test/04: Crash # unsupported element kind: closure:field
-mirrors/metadata_nested_constructor_call_test/05: Crash # unsupported element kind: closure:field
-mirrors/metadata_nested_constructor_call_test/06: Crash # unsupported element kind: closure:field
-mirrors/metadata_nested_constructor_call_test/07: Crash # unsupported element kind: closure:field
-mirrors/metadata_nested_constructor_call_test/08: Crash # unsupported element kind: closure:field
-mirrors/metadata_nested_constructor_call_test/09: Crash # unsupported element kind: closure:field
-mirrors/metadata_nested_constructor_call_test/none: Crash # unsupported element kind: closure:field
+mirrors/metadata_nested_constructor_call_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+mirrors/metadata_nested_constructor_call_test/02: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+mirrors/metadata_nested_constructor_call_test/03: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+mirrors/metadata_nested_constructor_call_test/04: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+mirrors/metadata_nested_constructor_call_test/05: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+mirrors/metadata_nested_constructor_call_test/06: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+mirrors/metadata_nested_constructor_call_test/07: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+mirrors/metadata_nested_constructor_call_test/08: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+mirrors/metadata_nested_constructor_call_test/09: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+mirrors/metadata_nested_constructor_call_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/method_mirror_location_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 mirrors/method_mirror_name_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/method_mirror_properties_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/method_mirror_returntype_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 mirrors/method_mirror_source_line_ending_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 mirrors/method_mirror_source_test: Crash # Instance of 'TypeOperator': type casts not implemented.
-mirrors/mirror_in_static_init_test/01: Crash # unsupported element kind: staticField:field
-mirrors/mirror_in_static_init_test/none: Crash # unsupported element kind: staticField:field
 mirrors/mirrors_nsm_test/dart2js: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/mirrors_nsm_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/mirrors_reader_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -643,7 +619,6 @@
 mirrors/to_string_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/top_level_accessors_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/type_argument_is_type_variable_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-mirrors/type_mirror_for_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for C<Type>.
 mirrors/type_variable_is_static_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/type_variable_owner_test/01: Crash # Instance of 'TypeOperator': type casts not implemented.
 mirrors/type_variable_owner_test/none: Crash # Instance of 'TypeOperator': type casts not implemented.
@@ -654,16 +629,15 @@
 mirrors/unnamed_library_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 mirrors/variable_is_const_test/01: Crash # Instance of 'TypeOperator': type casts not implemented.
 mirrors/variable_is_const_test/none: Crash # Instance of 'TypeOperator': type casts not implemented.
+profiler/metrics_num_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 profiler/metrics_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 profiler/user_tags_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 typed_data/constructor_checks_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-typed_data/float32x4_list_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<Float32x4>.
 typed_data/float32x4_shuffle_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 typed_data/float32x4_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-typed_data/int32x4_list_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<Int32x4>.
 typed_data/int32x4_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 typed_data/typed_data_hierarchy_int64_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
-typed_data/typed_data_hierarchy_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<double>.
 typed_data/typed_data_list_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 typed_data/typed_data_sublist_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for T.
 typed_data/typed_list_iterable_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
+convert/json_toEncodable_reviver_test : RuntimeError
diff --git a/tests/lib/mirrors/empty.dart b/tests/lib/mirrors/empty.dart
new file mode 100644
index 0000000..ee5f193
--- /dev/null
+++ b/tests/lib/mirrors/empty.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This library has no functions.
+library empty;
\ No newline at end of file
diff --git a/tests/lib/mirrors/empty_test.dart b/tests/lib/mirrors/empty_test.dart
new file mode 100644
index 0000000..506cdfb
--- /dev/null
+++ b/tests/lib/mirrors/empty_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'empty.dart';
+
+main() {
+  var empty = currentMirrorSystem().findLibrary(#empty);
+  print(empty.location);  // Used to crash VM.
+}
diff --git a/tests/lib/profiler/metrics_num_test.dart b/tests/lib/profiler/metrics_num_test.dart
index d6a6689..bdb5291 100644
--- a/tests/lib/profiler/metrics_num_test.dart
+++ b/tests/lib/profiler/metrics_num_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 
-import 'dart:profiler';
+import 'dart:developer';
 import 'package:expect/expect.dart';
 
 testGaugeDouble() {
diff --git a/tests/lib/profiler/metrics_test.dart b/tests/lib/profiler/metrics_test.dart
index 4dbf642..4e252ad 100644
--- a/tests/lib/profiler/metrics_test.dart
+++ b/tests/lib/profiler/metrics_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 
-import 'dart:profiler';
+import 'dart:developer';
 import 'package:expect/expect.dart';
 
 testGauge1() {
diff --git a/tests/lib/profiler/user_tags_test.dart b/tests/lib/profiler/user_tags_test.dart
index f09abcd..f4fc474 100644
--- a/tests/lib/profiler/user_tags_test.dart
+++ b/tests/lib/profiler/user_tags_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 
-import 'dart:profiler';
+import 'dart:developer';
 import 'package:expect/expect.dart';
 
 // Test that the default tag is set.
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index c241a5b..0519b92 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -716,6 +716,122 @@
     Expect.isFalse(file.existsSync());
   }
 
+  static testReadInto() async {
+    asyncTestStarted();
+    File file = new File(tempDirectory.path + "/out_read_into");
+
+    var openedFile = await file.open(mode: WRITE);
+    await openedFile.writeFrom(const [1, 2, 3]);
+
+    await openedFile.setPosition(0);
+    var list = [null, null, null];
+    Expect.equals(3, await openedFile.readInto(list));
+    Expect.listEquals([1, 2, 3], list);
+
+    read(start, end, length, expected) async {
+      var list = [null, null, null];
+      await openedFile.setPosition(0);
+      Expect.equals(length, await openedFile.readInto(list, start, end));
+      Expect.listEquals(expected, list);
+      return list;
+    }
+
+    await read(0, 3, 3, [1, 2, 3]);
+    await read(0, 2, 2, [1, 2, null]);
+    await read(1, 2, 1, [null, 1, null]);
+    await read(1, 3, 2, [null, 1, 2]);
+    await read(2, 3, 1, [null, null, 1]);
+    await read(0, 0, 0, [null, null, null]);
+
+    await openedFile.close();
+
+    asyncTestDone("testReadInto");
+  }
+
+  static void testReadIntoSync() {
+    File file = new File(tempDirectory.path + "/out_read_into_sync");
+
+    var openedFile = file.openSync(mode: WRITE);
+    openedFile.writeFromSync(const [1, 2, 3]);
+
+    openedFile.setPositionSync(0);
+    var list = [null, null, null];
+    Expect.equals(3, openedFile.readIntoSync(list));
+    Expect.listEquals([1, 2, 3], list);
+
+    read(start, end, length, expected) {
+      var list = [null, null, null];
+      openedFile.setPositionSync(0);
+      Expect.equals(length, openedFile.readIntoSync(list, start, end));
+      Expect.listEquals(expected, list);
+      return list;
+    }
+
+    read(0, 3, 3, [1, 2, 3]);
+    read(0, 2, 2, [1, 2, null]);
+    read(1, 2, 1, [null, 1, null]);
+    read(1, 3, 2, [null, 1, 2]);
+    read(2, 3, 1, [null, null, 1]);
+    read(0, 0, 0, [null, null, null]);
+
+    openedFile.closeSync();
+  }
+
+  static testWriteFrom() async {
+    asyncTestStarted();
+    File file = new File(tempDirectory.path + "/out_write_from");
+
+    var buffer = const [1, 2, 3];
+    var openedFile = await file.open(mode: WRITE);
+
+    await openedFile.writeFrom(buffer);
+    var result = []..addAll(buffer);;
+
+    write([start, end]) async {
+      var returnValue = await openedFile.writeFrom(buffer, start, end);
+      Expect.identical(openedFile, returnValue);
+      result.addAll(buffer.sublist(start, end));
+    }
+    await write(0, 3);
+    await write(0, 2);
+    await write(1, 2);
+    await write(1, 3);
+    await write(2, 3);
+    await write(0, 0);
+
+    var bytesFromFile = await file.readAsBytes();
+    Expect.listEquals(result, bytesFromFile);
+
+    await openedFile.close();
+
+    asyncTestDone("testWriteFrom");
+  }
+
+  static void testWriteFromSync() {
+    File file = new File(tempDirectory.path + "/out_write_from_sync");
+
+    var buffer = const [1, 2, 3];
+    var openedFile = file.openSync(mode: WRITE);
+
+    openedFile.writeFromSync(buffer);
+    var result = []..addAll(buffer);;
+
+    write([start, end]) {
+      var returnValue = openedFile.writeFromSync(buffer, start, end);
+      result.addAll(buffer.sublist(start, end));
+    }
+    write(0, 3);
+    write(0, 2);
+    write(1, 2);
+    write(1, 3);
+    write(2, 3);
+
+    var bytesFromFile = file.readAsBytesSync();
+    Expect.listEquals(result, bytesFromFile);
+
+    openedFile.closeSync();
+  }
+
   // Tests exception handling after file was closed.
   static void testCloseException() {
     bool exceptionCaught = false;
@@ -1327,6 +1443,10 @@
       testPosition();
       testTruncate();
       testTruncateSync();
+      testReadInto();
+      testReadIntoSync();
+      testWriteFrom();
+      testWriteFromSync();
       testCloseException();
       testCloseExceptionStream();
       testBufferOutOfBoundsException();
diff --git a/tests/standalone/io/platform_executable_test.dart b/tests/standalone/io/platform_executable_test.dart
new file mode 100644
index 0000000..1b6bce3
--- /dev/null
+++ b/tests/standalone/io/platform_executable_test.dart
@@ -0,0 +1,153 @@
+// 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.
+//
+// Process test program to test process communication.
+
+library PlatformExecutableTest;
+
+import "dart:io";
+
+const _SCRIPT_KEY = '_test_script';
+
+void expectEquals(a, b) {
+  if (a != b) {
+    throw 'Expected: $a\n'
+          '  Actual: $b';
+  }
+}
+
+void verify(String exePath, {String altPath}) {
+  var env = {_SCRIPT_KEY: 'yes'};
+  if (altPath != null) {
+    env['PATH'] = altPath;
+  }
+
+  var processResult = Process.runSync(exePath, [scriptPath],
+      includeParentEnvironment: false, runInShell: true, environment: env);
+
+  if (processResult.exitCode != 0) {
+    throw 'Error with process\n'
+          '$scriptPath'
+          'Exit code: ${processResult.exitCode}\n'
+          '   STDOUT: ${processResult.stdout}\n'
+          '   STDERR: ${processResult.stderr}\n';
+  }
+
+  var result = processResult.stdout.trim();
+  expectEquals(Platform.executable, result);
+}
+
+void testDartExecShouldNotBeInCurrentDir() {
+  var type = FileSystemEntity.typeSync(platformExeName);
+  expectEquals(FileSystemEntityType.NOT_FOUND, type);
+}
+
+void testShouldFailOutsidePath() {
+  var threw = false;
+  try {
+    Process.runSync(platformExeName, ['--version'],
+                    includeParentEnvironment: false,
+                    environment: {_SCRIPT_KEY: 'yes', 'PATH': ''});
+  } catch (_) {
+    threw = true;
+  }
+
+  if (!threw) {
+    throw 'Expected running the dart executable – "$platformExeName" without'
+          ' the parent environment or path to fail.';
+  }
+}
+
+void testShouldSucceedWithSourcePlatformExecutable() {
+  //print('*** Running normally');
+  verify(Platform.executable);
+}
+
+void testExeSymLinked(Directory dir) {
+  var dirUri = new Uri.directory(dir.path);
+  var link = new Link.fromUri(dirUri.resolve('dart_exe_link'));
+  link.createSync(Platform.executable);
+  //print('*** Creating a sym-link to the executable');
+  verify(link.path);
+}
+
+void testPathToDirWithExeSymLinked(Directory dir) {
+  var dirUri = new Uri.directory(dir.path);
+  var link = new Link.fromUri(dirUri.resolve('dart_exe_link'));
+  link.createSync(Platform.executable);
+  //print('*** Path to a directory that contains a sym-link to dart bin');
+  verify('dart_exe_link', altPath: dir.path);
+}
+
+/// Create a sym-link to the SDK directory and run 'dart' from that path
+void testExeDirSymLinked(Directory dir) {
+  var dirUri = new Uri.directory(dir.path);
+
+  var linkDirUri = dirUri.resolve('dart_bin_dir_link');
+  var link = new Link.fromUri(linkDirUri);
+
+  var exeFile = new File(Platform.executable);
+
+  link.createSync(exeFile.parent.path);
+
+  var linkedBin =
+      new Uri.directory(linkDirUri.toFilePath()).resolve(platformExeName);
+
+  //print('*** Running in a sym-linked directory');
+  verify(linkedBin.toFilePath());
+}
+
+void testPathPointsToSymLinkedSDKPath(Directory dir) {
+  var dirUri = new Uri.directory(dir.path);
+
+  var linkDirUri = dirUri.resolve('dart_bin_dir_link');
+  var link = new Link.fromUri(linkDirUri);
+
+  var exeFile = new File(Platform.executable);
+
+  link.createSync(exeFile.parent.path);
+
+  //print('*** Path points to a sym-linked SDK dir');
+  verify(platformExeName, altPath: link.path);
+}
+
+void testPathToSDKDir() {
+  var exeFile = new File(Platform.executable);
+  var binDirPath = exeFile.parent.path;
+
+  //print('*** Running with PATH env set to environment - fixed in 16994 - thanks!');
+  verify(platformExeName, altPath: binDirPath);
+}
+
+void withTempDir(void test(Directory dir)) {
+  var tempDir = Directory.systemTemp.createTempSync('dart.sdk.test.');
+  try {
+    test(tempDir);
+  } finally {
+    tempDir.deleteSync(recursive: true);
+  }
+}
+
+String get platformExeName {
+  var raw = new Uri.file(Platform.executable);
+  return raw.pathSegments.last;
+}
+
+String get scriptPath => Platform.script.toFilePath();
+
+void main() {
+  if (Platform.environment.containsKey(_SCRIPT_KEY)) {
+    print(Platform.executable);
+    return;
+  }
+
+  testDartExecShouldNotBeInCurrentDir();
+  testShouldSucceedWithSourcePlatformExecutable(); /// 00: ok
+  withTempDir(testExeSymLinked); /// 01: ok
+  withTempDir(testExeDirSymLinked); /// 02: ok
+  testPathToSDKDir(); /// 03: ok
+  withTempDir(testPathPointsToSymLinkedSDKPath); /// 04: ok
+  withTempDir(testPathToDirWithExeSymLinked); /// 05: ok
+  testShouldFailOutsidePath(); /// 06: ok
+}
diff --git a/tests/standalone/io/platform_test.dart b/tests/standalone/io/platform_test.dart
index e3ee4d4..269a487 100644
--- a/tests/standalone/io/platform_test.dart
+++ b/tests/standalone/io/platform_test.dart
@@ -25,6 +25,15 @@
   var environment = Platform.environment;
   Expect.isTrue(environment is Map<String, String>);
   Expect.isTrue(Platform.executable.contains('dart'));
+  if (!Platform.isWindows) {
+    Expect.isTrue(Platform.executable.startsWith('/'));
+  } else {
+    // This assumes that tests (both locally and on the bots) are
+    // running off a location referred to by a drive letter. If a UNC
+    // location is used or long names ("\\?\" prefix) is used this
+    // needs to be fixed.
+    Expect.equals(Platform.executable.substring(1, 3), ':\\');
+  }
   // Move directory to be sure script is correct.
   var oldDir = Directory.current;
   Directory.current = Directory.current.parent;
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index f0357bc..ee2f9e0 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -17,6 +17,15 @@
 package/package_isolate_test: Fail # Issue 12474
 io/observatory_test: Fail
 
+[ $runtime == vm && ($system == macos || $system == windows) ]
+io/platform_executable_test/01: RuntimeError # Issue 16994
+io/platform_executable_test/02: RuntimeError # Issue 16994
+io/platform_executable_test/04: RuntimeError # Issue 16994
+io/platform_executable_test/05: RuntimeError # Issue 16994
+
+[ $runtime == vm && $system == windows ]
+io/platform_executable_test/06: RuntimeError # NEEDS TRIAGE (kevmoo)
+
 [ $runtime == vm && $checked ]
 # These tests have type errors on purpose.
 io/process_invalid_arguments_test: Fail, OK
@@ -169,11 +178,8 @@
 [ $compiler == dart2js && $cps_ir ]
 array_bounds_check_generalization_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 constant_left_shift_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-coverage_test: Crash # unsupported element kind: context:field
 io/addlatexhash_test: Crash # (try {test(tempDir.path);}finally {tempDir.delete(recursive:true);}): try/finally
-io/async_catch_errors_test: Crash # unsupported element kind: events:field
-io/create_recursive_test: Crash # unsupported element kind: context:field
-io/dependency_graph_test: Crash # unsupported element kind: UnableToRun:field
+io/create_recursive_test: Crash #  try/finally
 io/directory_chdir_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/directory_error_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/directory_fuzz_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -185,12 +191,10 @@
 io/file_copy_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/file_error_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/file_invalid_arguments_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-io/file_lock_test: Crash # unsupported element kind: context:field
 io/file_read_encoded_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-io/file_stat_test: Crash # unsupported element kind: context:field
 io/file_system_delete_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/file_system_links_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-io/file_system_watcher_test: Crash # unsupported element kind: context:field
+io/file_system_watcher_test: Crash #  Unhandled node
 io/file_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/file_typed_data_test: Crash # Please triage this failure.
 io/file_uri_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -204,7 +208,6 @@
 io/http_headers_test: Crash #  Unhandled node
 io/http_parser_test: Crash #  Unhandled node
 io/http_proxy_test: Crash # Please triage this failure.
-io/http_server_early_client_close_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
 io/http_server_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/https_bad_certificate_test: Crash #  cannot handle async/sync*/async* functions
 io/https_server_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -212,14 +215,15 @@
 io/internet_address_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/issue_22636_test: Crash #  cannot handle async/sync*/async* functions
 io/issue_22637_test: Crash #  cannot handle async/sync*/async* functions
-io/link_async_test: Crash # unsupported element kind: context:field
-io/link_test: Crash # unsupported element kind: context:field
+io/link_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/link_uri_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/observatory_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-io/parent_test: Crash # unsupported element kind: context:field
+io/platform_executable_test/01: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
+io/platform_executable_test/02: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
+io/platform_executable_test/04: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
+io/platform_executable_test/05: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
 io/platform_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/process_invalid_arguments_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-io/process_run_test: Crash # Instance of 'TypeOperator': type check unimplemented for List<int>.
 io/raw_datagram_socket_test: Crash #  Unhandled node
 io/raw_secure_server_closing_test: Crash # Please triage this failure.
 io/raw_secure_server_socket_argument_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
@@ -231,14 +235,13 @@
 io/raw_socket_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/raw_socket_typed_data_test: Crash # Please triage this failure.
 io/regress_21160_test: Crash #  Unhandled node
-io/resolve_symbolic_links_test: Crash # unsupported element kind: context:field
 io/secure_client_raw_server_test: Crash #  Unhandled node
 io/secure_server_closing_test: Crash # Please triage this failure.
 io/secure_server_socket_test: Crash # Please triage this failure.
 io/secure_socket_alpn_test: Crash # Instance of 'TypeOperator': type casts not implemented.
 io/secure_socket_argument_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/secure_socket_bad_data_test: Crash #  Unhandled node
-io/skipping_dart2js_compilations_test: Crash # unsupported element kind: currentWorkingDirectory:field
+io/skipping_dart2js_compilations_test: Crash #  Unhandled node
 io/sleep_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/socket_bind_test: Crash #  cannot handle async/sync*/async* functions
 io/socket_close_test: Crash #  Unhandled node
@@ -246,17 +249,13 @@
 io/socket_source_address_test: Crash #  cannot handle async/sync*/async* functions
 io/socket_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/socket_upgrade_to_secure_test: Crash # Please triage this failure.
-io/status_file_parser_test: Crash # unsupported element kind: IssueNumberPattern:field
 io/stdout_stderr_terminal_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-io/test_extension_fail_test: Crash # unsupported element kind: context:field
-io/test_extension_test: Crash # unsupported element kind: context:field
+io/test_extension_fail_test: Crash #  Unhandled node
+io/test_extension_test: Crash #  Unhandled node
 io/test_runner_test: Crash #  Unhandled node
 io/uri_platform_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/web_socket_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-io/windows_environment_test: Crash # unsupported element kind: context:field
 io/windows_file_system_links_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 io/zlib_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
 priority_queue_stress_test: RuntimeError # Please triage this failure.
-status_expression_test: Crash # unsupported element kind: regexp:field
-typed_array_test: Crash # unsupported element kind: float64:field
-verified_mem_test: Crash # unsupported element kind: a:field
+status_expression_test: RuntimeError # Please triage this failure.
diff --git a/third_party/pkg_tested/pkg_tested.status b/third_party/pkg_tested/pkg_tested.status
index 066479a..c18a94c 100644
--- a/third_party/pkg_tested/pkg_tested.status
+++ b/third_party/pkg_tested/pkg_tested.status
@@ -20,9 +20,9 @@
 dart_style/test/formatter_test: Skip # The test controller does not take into account that tests take much longer in debug mode or on simulators/mips.
 
 [ $compiler == dart2js && $cps_ir ]
-analyzer_cli/test/error_test: Crash # unsupported element kind: _escapeRegExp:field
+analyzer_cli/test/error_test: Crash # (try {return fn(tempDir);}finally {new Directory(tempDir).deleteSync(recursive:true);}): try/finally
 analyzer_cli/test/options_test: Crash #  try/finally
 dart_style/test/command_line_test: Crash #  try/finally
 dart_style/test/formatter_test: Crash #  try/finally
-dart_style/test/io_test: Crash # unsupported element kind: _asyncBody:field
+dart_style/test/io_test: Crash #  try/finally
 dart_style/test/source_code_test: Crash #  try/finally
diff --git a/tools/VERSION b/tools/VERSION
index 249ddaf..a79c18d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 11
 PATCH 0
-PRERELEASE 2
+PRERELEASE 3
 PRERELEASE_PATCH 0
diff --git a/tools/bots/dart_sdk.py b/tools/bots/dart_sdk.py
index b2a3b06..cbaecd6 100644
--- a/tools/bots/dart_sdk.py
+++ b/tools/bots/dart_sdk.py
@@ -30,6 +30,21 @@
     Run([sys.executable, './tools/build.py', '--mode=release',
          '--arch=ia32', 'dartdocgen'])
 
+def CreateUploadVersionFile():
+  file_path = os.path.join(bot_utils.DART_DIR,
+                           utils.GetBuildRoot(BUILD_OS, 'release', 'ia32'),
+                           'VERSION')
+  with open(file_path, 'w') as fd:
+    fd.write(utils.GetVersionFileContent())
+  DartArchiveUploadVersionFile(file_path)
+
+def DartArchiveUploadVersionFile(version_file):
+  namer = bot_utils.GCSNamer(CHANNEL, bot_utils.ReleaseType.RAW)
+  revision = utils.GetSVNRevision()
+  for revision in [revision, 'latest']:
+    destination = namer.version_filepath(revision)
+    DartArchiveFile(version_file, destination, checksum_files=False)
+
 def CreateUploadSDKZips():
   with bot.BuildStep('Create and upload sdk zips'):
     sdk32_path = os.path.join(bot_utils.DART_DIR,
@@ -174,4 +189,5 @@
 if __name__ == '__main__':
   CreateUploadSDK()
   if BUILD_OS == 'linux':
+    CreateUploadVersionFile()
     CreateUploadAPIDocs()
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 5f3ff48..ca5e772 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -233,9 +233,6 @@
            join(RESOURCE),
            ignore=ignore_patterns('.svn'))
 
-  copytree(join(SNAPSHOT, 'core_stubs'),
-           join(RESOURCE, 'dart', 'core_stubs'))
-
   # Copy in 7zip for Windows.
   if HOST_OS == 'win32':
     copytree(join(HOME, 'third_party', '7zip'),
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index eaefc23..5417092 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -13,7 +13,7 @@
   "dartium_chromium_commit": "62a7524d4f71c9e0858d24b0aa1bbff3a2d09bff",
   "chromium_base_revision": "297060",
   "dartium_webkit_branch": "/blink/branches/dart/dartium",
-  "dartium_webkit_revision": "195425",
+  "dartium_webkit_revision": "195544",
 
   "args_tag": "@0.13.0",
   "barback_rev" : "@29ee90dbcf77cfd64632fa2797a4c8a4f29a4b51",
diff --git a/tools/dom/src/Validators.dart b/tools/dom/src/Validators.dart
index ac51da1..5724770 100644
--- a/tools/dom/src/Validators.dart
+++ b/tools/dom/src/Validators.dart
@@ -161,60 +161,99 @@
 
   /// Aggressively try to remove node.
   void _removeNode(Node node, Node parent) {
-    // If we have the parent, it's presumably already passed more sanitization or
-    // is the fragment, so ask it to remove the child. And if that fails try to
-    // set the outer html.
+    // If we have the parent, it's presumably already passed more sanitization
+    // or is the fragment, so ask it to remove the child. And if that fails
+    // try to set the outer html.
     if (parent == null) {
       node.remove();
     } else {
       parent._removeChild(node);
     }
   }
-  
+
+  /// Sanitize the element, assuming we can't trust anything about it.
+  void _sanitizeUntrustedElement(Element element, Node parent) {
+    // If the _hasCorruptedAttributes does not successfully return false,
+    // then we consider it corrupted and remove.
+    // TODO(alanknight): This is a workaround because on Firefox
+    // embed/object
+    // tags typeof is "function", not "object". We don't recognize them, and
+    // can't call methods. This does mean that you can't explicitly allow an
+    // embed tag. The only thing that will let it through is a null
+    // sanitizer that doesn't traverse the tree at all. But sanitizing while
+    // allowing embeds seems quite unlikely.
+    var corrupted = true;
+    var attrs;
+    var isAttr;
+    try {
+      // If getting/indexing attributes throws, count that as corrupt.
+      attrs = element.attributes;
+      isAttr = attrs['is'];
+      corrupted = Element._hasCorruptedAttributes(element);
+    } catch(e) {}
+     var elementText = 'element unprintable';
+    try {
+      elementText = element.toString();
+    } catch(e) {}
+    var elementTagName = 'element tag unavailable';
+    try {
+      elementTagName = element.tagName;
+    } catch(e) {}
+    _sanitizeElement(element, parent, corrupted, elementText, elementTagName,
+        attrs, isAttr);
+  }
+
+  /// Having done basic sanity checking on the element, and computed the
+  /// important attributes we want to check, remove it if it's not valid
+  /// or not allowed, either as a whole or particular attributes.
+  void _sanitizeElement(Element element, Node parent, bool corrupted,
+      String text, String tag, Map attrs, String isAttr) {
+    if (false != corrupted) {
+      window.console.warn(
+          'Removing element due to corrupted attributes on <$text>');
+       _removeNode(element, parent);
+       return;
+    }
+    if (!validator.allowsElement(element)) {
+      window.console.warn(
+          'Removing disallowed element <$tag>');
+      _removeNode(element, parent);
+      return;
+    }
+
+    if (isAttr != null) {
+      if (!validator.allowsAttribute(element, 'is', isAttr)) {
+        window.console.warn('Removing disallowed type extension '
+            '<$tag is="$isAttr">');
+        _removeNode(element, parent);
+        return;
+      }
+    }
+
+    // TODO(blois): Need to be able to get all attributes, irrespective of
+    // XMLNS.
+    var keys = attrs.keys.toList();
+    for (var i = attrs.length - 1; i >= 0; --i) {
+      var name = keys[i];
+      if (!validator.allowsAttribute(element, name.toLowerCase(),
+          attrs[name])) {
+        window.console.warn('Removing disallowed attribute '
+            '<$tag $name="${attrs[name]}">');
+        attrs.remove(name);
+      }
+    }
+
+    if (element is TemplateElement) {
+      TemplateElement template = element;
+      sanitizeTree(template.content);
+     }
+  }
+
+  /// Sanitize the node and its children recursively.
   void sanitizeNode(Node node, Node parent) {
     switch (node.nodeType) {
       case Node.ELEMENT_NODE:
-        Element element = node;
-        if (element._hasCorruptedAttributes) {
-          window.console.warn('Removing element due to corrupted attributes on <${element}>');
-          _removeNode(node, parent);
-          break;
-        }
-        var attrs = element.attributes;
-        if (!validator.allowsElement(element)) {
-          window.console.warn(
-              'Removing disallowed element <${element.tagName}>');
-          _removeNode(node, parent);
-          break;
-        }
-
-        var isAttr = attrs['is'];
-        if (isAttr != null) {
-          if (!validator.allowsAttribute(element, 'is', isAttr)) {
-            window.console.warn('Removing disallowed type extension '
-                '<${element.tagName} is="$isAttr">');
-            _removeNode(node, parent);
-            break;
-          }
-        }
-
-        // TODO(blois): Need to be able to get all attributes, irrespective of
-        // XMLNS.
-        var keys = attrs.keys.toList();
-        for (var i = attrs.length - 1; i >= 0; --i) {
-          var name = keys[i];
-          if (!validator.allowsAttribute(element, name.toLowerCase(),
-              attrs[name])) {
-            window.console.warn('Removing disallowed attribute '
-                '<${element.tagName} $name="${attrs[name]}">');
-            attrs.remove(name);
-          }
-        }
-
-        if (element is TemplateElement) {
-          TemplateElement template = element;
-          sanitizeTree(template.content);
-        }
+        _sanitizeUntrustedElement(node, parent);
         break;
       case Node.COMMENT_NODE:
       case Node.DOCUMENT_FRAGMENT_NODE:
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 10f842c..f5b165b 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -1392,7 +1392,7 @@
    * Those attributes are: attributes, lastChild, children, previousNode and tagName.
    */
 $if DART2JS
-  bool get _hasCorruptedAttributes {
+  static bool _hasCorruptedAttributes(Element element) {
      return JS('bool', r'''
        (function(element) {
          if (!(element.attributes instanceof NamedNodeMap)) {
@@ -1410,11 +1410,11 @@
 	   }
 	 }
 	 return false;
-          })(#)''', this);
+          })(#)''', element);
   }
 $else
   // Dartium isn't affected by these attacks, because it goes directly to the C++ API.
-  bool get _hasCorruptedAttributes => false;
+  static bool _hasCorruptedAttributes(Element element) => false;
 $endif
 
 $if DART2JS
diff --git a/tools/utils.py b/tools/utils.py
index 2189dba..ec6312e 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -6,6 +6,8 @@
 # scripts.
 
 import commands
+import datetime
+import json
 import os
 import platform
 import re
@@ -318,6 +320,21 @@
 def GetVersion():
   return GetSemanticSDKVersion()
 
+
+# The editor used to produce the VERSION file put on gcs. We now produce this
+# in the bots archiving the sdk.
+# The content looks like this:
+#{
+#  "date": "2015-05-28",
+#  "version": "1.11.0-edge.131653",
+#  "revision": "535394c2657ede445142d8a92486d3899bbf49b5"
+#}
+def GetVersionFileContent():
+  result = {"date": str(datetime.date.today()),
+            "version": GetVersion(),
+            "revision": GetGitRevision()}
+  return json.dumps(result, indent=2)
+
 def GetChannel():
   version = ReadVersionFile()
   return version.channel
@@ -388,6 +405,19 @@
     return GetGitNumber()
   return GetSemanticSDKVersion()
 
+
+def GetGitRevision():
+  p = subprocess.Popen(['git', 'log', '-n', '1', '--pretty=format:%H'],
+                       stdout = subprocess.PIPE,
+                       stderr = subprocess.STDOUT, shell=IsWindows(),
+                       cwd = DART_DIR)
+  output, _ = p.communicate()
+  # We expect a full git hash
+  if len(output) != 40:
+    print "Warning: could not parse git commit, output was %s" % output
+    return None
+  return output
+
 # To eliminate clashing with older archived builds on bleding edge we add
 # a base number bigger the largest svn revision (this also gives us an easy
 # way of seeing if an archive comes from git based or svn based commits).
@@ -507,7 +537,8 @@
   print "GuessCpus() -> ", GuessCpus()
   print "IsWindows() -> ", IsWindows()
   print "GuessVisualStudioPath() -> ", GuessVisualStudioPath()
-
+  print "GetGitRevision() -> ", GetGitRevision()
+  print "GetVersionFileContent() -> ", GetVersionFileContent()
 
 class Error(Exception):
   pass
diff --git a/utils/pub/pub.gyp b/utils/pub/pub.gyp
index 13d0b09..f15df32 100644
--- a/utils/pub/pub.gyp
+++ b/utils/pub/pub.gyp
@@ -37,34 +37,6 @@
         },
       ],
     },
-    {
-      'target_name': 'core_stubs',
-      'type': 'none',
-      'dependencies': [
-        '../../runtime/dart-runtime.gyp:dart',
-        '../../pkg/pkg.gyp:pkg_packages',
-        '../../pkg/pkg_files.gyp:pkg_files_stamp'
-      ],
-      'actions': [
-        {
-          'action_name': 'generate_core_stubs',
-          'inputs': [
-            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
-            '../../sdk/lib/_internal/libraries.dart',
-            '<(SHARED_INTERMEDIATE_DIR)/pkg_files.stamp',
-          ],
-          'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/core_stubs/dart_io.dart',
-          ],
-          'action': [
-            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
-            '--package-root=<(PRODUCT_DIR)/packages/',
-            '../../pkg/stub_core_library/bin/stub_core_library.dart',
-            '<(SHARED_INTERMEDIATE_DIR)/core_stubs',
-          ],
-        }
-      ]
-    },
     # Other targets depend on pub files, but have to many inputs, which causes
     # issues on some platforms.
     # This target lists all the files in sdk/lib/_internal/pub,